Python Matplotlib 自定义缩放功能无效
Python Matplotlib custom zoom function isn't working
我正在为交互式 Mandelbrot 集显示编写代码,我希望缩放功能在每次使用时更新图像。所以我使用 Matplotlib 事件处理来创建自定义缩放功能。
已有的缩放功能会在您放大时对图像进行像素化处理,因为它会放大同一幅图像。我的缩放应该在每次拖动鼠标时更新图像。
但是没用。每次我缩放一次,图都不会改变形状,所以图像本身会拉伸。再次缩放,它只是在 原始图片 上缩放。滴答声甚至不会一直变化。试一试——这是我的代码,图片由 Trenton McKinney 提供:
# Get necessary packages
import numpy as np
from matplotlib import pyplot as plt
# Calculation
COLORS = [(1, 0, 0)]
for transition in [[0, 1, 0], [-1, 0, 0], [0, 0, 1], [0, -1, 0], [1, 0, 0]]:
for _ in range(10):
r, g, b = COLORS[-1]
r = round(r + transition[0] / 10, 1)
g = round(g + transition[1] / 10, 1)
b = round(b + transition[2] / 10, 1)
COLORS.append((r, g, b))
def color(n):
z = complex(0, 0)
c = n
for n in range(len(COLORS)):
z = z ** 2 + c
if abs(z) > 2:
return COLORS[n]
return (0, 0, 0)
def get_data(c1, c2):
d = []
for i in np.linspace(c1.imag, c2.imag, num = 500):
rvals = [complex(r, i) for r in np.linspace(c1.real, c2.real, num = 500)]
d.append(list(map(color, rvals)))
return d
# Interface
corner1 = (-2, -2)
corner2 = (2, 2)
def display_data(c1, c2):
data = get_data(c1, c2)
image.set_data(data)
figure.show()
def startzoom(event):
global corner1, corner2
if event.button:
x = event.xdata
y = event.ydata
corner1 = corner2 = (x, y)
def stopzoom(event):
global corner1, corner2
if event.button:
x = event.xdata
y = event.ydata
corner2 = (x, y)
if corner1 == corner2:
corner1, corner2 = (-2, -2), (2, 2)
display_data(complex(*corner1), complex(*corner2))
# Put it all together
data = get_data(complex(*corner1), complex(*corner2))
figure, axes = plt.subplots()
axes.set_title("Mandelbrot Set")
axes.set_xlabel("Real")
axes.set_ylabel("Imaginary")
image = axes.imshow(list(reversed(data)), extent = [-2, 2, -2, 2])
figure.canvas.mpl_connect("button_press_event", startzoom)
figure.canvas.mpl_connect("button_release_event", stopzoom)
figure.show()
我该怎么办?
我编辑了你的 display_data
函数如下:
def display_data(c1, c2):
data = get_data(c1, c2)
axes.imshow(list(reversed(data)), extent = [corner1[0], corner2[0], corner1[1], corner2[1]])
plt.show()
您应该在每次用户单击绘图时更新 extent
参数值,以便更新图像边框。
此外,我添加了 axes.invert_xaxis()
和 axes.invert_yaxis()
这样缩放在每个方向都有效:从左下角到右上角,从左上角到右下角,从右上角到左下角和从右下角到左上角。
完整代码
import numpy as np
from matplotlib import pyplot as plt
# Calculation
COLORS = [(1, 0, 0)]
for transition in [[0, 1, 0], [-1, 0, 0], [0, 0, 1], [0, -1, 0], [1, 0, 0]]:
for _ in range(10):
r, g, b = COLORS[-1]
r = round(r + transition[0] / 10, 1)
g = round(g + transition[1] / 10, 1)
b = round(b + transition[2] / 10, 1)
COLORS.append((r, g, b))
def color(n):
z = complex(0, 0)
c = n
for n in range(len(COLORS)):
z = z ** 2 + c
if abs(z) > 2:
return COLORS[n]
return (0, 0, 0)
def get_data(c1, c2):
d = []
for i in np.linspace(c1.imag, c2.imag, num = 500):
rvals = [complex(r, i) for r in np.linspace(c1.real, c2.real, num = 500)]
d.append(list(map(color, rvals)))
return d
# Interface
corner1 = (-2, -2)
corner2 = (2, 2)
def display_data(c1, c2):
data = get_data(c1, c2)
axes.imshow(list(reversed(data)), extent = [corner1[0], corner2[0], corner1[1], corner2[1]])
plt.show()
def startzoom(event):
global corner1, corner2
if event.button:
x = event.xdata
y = event.ydata
corner1 = corner2 = (x, y)
def stopzoom(event):
global corner1, corner2
if event.button:
x = event.xdata
y = event.ydata
corner2 = (x, y)
if corner1 == corner2:
corner1, corner2 = (-2, -2), (2, 2)
display_data(complex(*corner1), complex(*corner2))
# Put it all together
data = get_data(complex(*corner1), complex(*corner2))
figure, axes = plt.subplots()
axes.set_title("Mandelbrot Set")
axes.set_xlabel("Real")
axes.set_ylabel("Imaginary")
image = axes.imshow(list(reversed(data)), extent = [-2, 2, -2, 2])
figure.canvas.mpl_connect("button_press_event", startzoom)
figure.canvas.mpl_connect("button_release_event", stopzoom)
plt.show()
我正在为交互式 Mandelbrot 集显示编写代码,我希望缩放功能在每次使用时更新图像。所以我使用 Matplotlib 事件处理来创建自定义缩放功能。
已有的缩放功能会在您放大时对图像进行像素化处理,因为它会放大同一幅图像。我的缩放应该在每次拖动鼠标时更新图像。
但是没用。每次我缩放一次,图都不会改变形状,所以图像本身会拉伸。再次缩放,它只是在 原始图片 上缩放。滴答声甚至不会一直变化。试一试——这是我的代码,图片由 Trenton McKinney 提供:
# Get necessary packages
import numpy as np
from matplotlib import pyplot as plt
# Calculation
COLORS = [(1, 0, 0)]
for transition in [[0, 1, 0], [-1, 0, 0], [0, 0, 1], [0, -1, 0], [1, 0, 0]]:
for _ in range(10):
r, g, b = COLORS[-1]
r = round(r + transition[0] / 10, 1)
g = round(g + transition[1] / 10, 1)
b = round(b + transition[2] / 10, 1)
COLORS.append((r, g, b))
def color(n):
z = complex(0, 0)
c = n
for n in range(len(COLORS)):
z = z ** 2 + c
if abs(z) > 2:
return COLORS[n]
return (0, 0, 0)
def get_data(c1, c2):
d = []
for i in np.linspace(c1.imag, c2.imag, num = 500):
rvals = [complex(r, i) for r in np.linspace(c1.real, c2.real, num = 500)]
d.append(list(map(color, rvals)))
return d
# Interface
corner1 = (-2, -2)
corner2 = (2, 2)
def display_data(c1, c2):
data = get_data(c1, c2)
image.set_data(data)
figure.show()
def startzoom(event):
global corner1, corner2
if event.button:
x = event.xdata
y = event.ydata
corner1 = corner2 = (x, y)
def stopzoom(event):
global corner1, corner2
if event.button:
x = event.xdata
y = event.ydata
corner2 = (x, y)
if corner1 == corner2:
corner1, corner2 = (-2, -2), (2, 2)
display_data(complex(*corner1), complex(*corner2))
# Put it all together
data = get_data(complex(*corner1), complex(*corner2))
figure, axes = plt.subplots()
axes.set_title("Mandelbrot Set")
axes.set_xlabel("Real")
axes.set_ylabel("Imaginary")
image = axes.imshow(list(reversed(data)), extent = [-2, 2, -2, 2])
figure.canvas.mpl_connect("button_press_event", startzoom)
figure.canvas.mpl_connect("button_release_event", stopzoom)
figure.show()
我该怎么办?
我编辑了你的 display_data
函数如下:
def display_data(c1, c2):
data = get_data(c1, c2)
axes.imshow(list(reversed(data)), extent = [corner1[0], corner2[0], corner1[1], corner2[1]])
plt.show()
您应该在每次用户单击绘图时更新 extent
参数值,以便更新图像边框。
此外,我添加了 axes.invert_xaxis()
和 axes.invert_yaxis()
这样缩放在每个方向都有效:从左下角到右上角,从左上角到右下角,从右上角到左下角和从右下角到左上角。
完整代码
import numpy as np
from matplotlib import pyplot as plt
# Calculation
COLORS = [(1, 0, 0)]
for transition in [[0, 1, 0], [-1, 0, 0], [0, 0, 1], [0, -1, 0], [1, 0, 0]]:
for _ in range(10):
r, g, b = COLORS[-1]
r = round(r + transition[0] / 10, 1)
g = round(g + transition[1] / 10, 1)
b = round(b + transition[2] / 10, 1)
COLORS.append((r, g, b))
def color(n):
z = complex(0, 0)
c = n
for n in range(len(COLORS)):
z = z ** 2 + c
if abs(z) > 2:
return COLORS[n]
return (0, 0, 0)
def get_data(c1, c2):
d = []
for i in np.linspace(c1.imag, c2.imag, num = 500):
rvals = [complex(r, i) for r in np.linspace(c1.real, c2.real, num = 500)]
d.append(list(map(color, rvals)))
return d
# Interface
corner1 = (-2, -2)
corner2 = (2, 2)
def display_data(c1, c2):
data = get_data(c1, c2)
axes.imshow(list(reversed(data)), extent = [corner1[0], corner2[0], corner1[1], corner2[1]])
plt.show()
def startzoom(event):
global corner1, corner2
if event.button:
x = event.xdata
y = event.ydata
corner1 = corner2 = (x, y)
def stopzoom(event):
global corner1, corner2
if event.button:
x = event.xdata
y = event.ydata
corner2 = (x, y)
if corner1 == corner2:
corner1, corner2 = (-2, -2), (2, 2)
display_data(complex(*corner1), complex(*corner2))
# Put it all together
data = get_data(complex(*corner1), complex(*corner2))
figure, axes = plt.subplots()
axes.set_title("Mandelbrot Set")
axes.set_xlabel("Real")
axes.set_ylabel("Imaginary")
image = axes.imshow(list(reversed(data)), extent = [-2, 2, -2, 2])
figure.canvas.mpl_connect("button_press_event", startzoom)
figure.canvas.mpl_connect("button_release_event", stopzoom)
plt.show()