Python matplotlib - 缩放重绘
Python matplotlib - replot on zoom
我发现 Matplotlib 库可以为其绘图设置动画并处理事件 - 如鼠标单击。我需要为交互式 Mandelbrot 集缩放制作 easy 代码。出于明显的原因,我不能以无限的精度绘制所有内容;)我认为也许在用户缩放之后,绘图应该采用新的边界并在新的边界中绘制 Mandelbrot 集的一部分,具有足够好的新精度。
有没有简单的方法可以做到这一点?还是只是一种方式? :)
查看 event-handling functionality, for which a simple example is provided here。
您只需要在上面链接的示例中的 "onpress"(连接到鼠标事件)等函数中添加您自己的重新计算代码。像下面这样的东西对我有用:
import matplotlib.pyplot as plt
import numpy as np
class ZoomPlot():
def __init__(self):
self.fig = plt.figure()
self.ax = self.fig.add_subplot(111)
self.xmin = -2.5; self.xmax = 1.0;
self.ymin = -1.5; self.ymax = 1.5;
self.xpress = self.xmin
self.xrelease = self.xmax
self.ypress = self.ymin
self.yrelease = self.ymax
self.resolution = 200
self.maxiters = 30
self.fig.canvas.mpl_connect('button_press_event', self.onpress)
self.fig.canvas.mpl_connect('button_release_event', self.onrelease)
self.plot_fixed_resolution(self.xmin, self.xmax,
self.ymin, self.ymax)
def mandlebrot(self, X, Y):
C = X + Y*1j
Z = C
divtime = self.maxiters + np.zeros(Z.shape, dtype=int)
for n in range(self.maxiters):
Z = Z**2 + C
diverge = Z*np.conj(Z) > 2**2
div_now = diverge & (divtime == self.maxiters)
divtime[div_now] = n
Z[diverge] = 2
return divtime
def plot_fixed_resolution(self, x1, x2, y1, y2):
x = np.linspace(x1, x2, self.resolution)
y = np.linspace(y1, y2, self.resolution)
X, Y = np.meshgrid(x, y)
C = self.mandlebrot(X, Y)
self.ax.clear()
self.ax.set_xlim(x1, x2)
self.ax.set_ylim(y1, y2)
self.ax.pcolormesh(X, Y, C)
self.fig.canvas.draw()
def onpress(self, event):
if event.button != 1: return
self.xpress = event.xdata
self.ypress = event.ydata
def onrelease(self, event):
if event.button != 1: return
self.xrelease = event.xdata
self.yrelease = event.ydata
self.xmin = min(self.xpress, self.xrelease)
self.xmax = max(self.xpress, self.xrelease)
self.ymin = min(self.ypress, self.yrelease)
self.ymax = max(self.ypress, self.yrelease)
self.plot_fixed_resolution(self.xmin, self.xmax,
self.ymin, self.ymax)
plot = ZoomPlot()
plt.show()
我发现 Matplotlib 库可以为其绘图设置动画并处理事件 - 如鼠标单击。我需要为交互式 Mandelbrot 集缩放制作 easy 代码。出于明显的原因,我不能以无限的精度绘制所有内容;)我认为也许在用户缩放之后,绘图应该采用新的边界并在新的边界中绘制 Mandelbrot 集的一部分,具有足够好的新精度。
有没有简单的方法可以做到这一点?还是只是一种方式? :)
查看 event-handling functionality, for which a simple example is provided here。
您只需要在上面链接的示例中的 "onpress"(连接到鼠标事件)等函数中添加您自己的重新计算代码。像下面这样的东西对我有用:
import matplotlib.pyplot as plt
import numpy as np
class ZoomPlot():
def __init__(self):
self.fig = plt.figure()
self.ax = self.fig.add_subplot(111)
self.xmin = -2.5; self.xmax = 1.0;
self.ymin = -1.5; self.ymax = 1.5;
self.xpress = self.xmin
self.xrelease = self.xmax
self.ypress = self.ymin
self.yrelease = self.ymax
self.resolution = 200
self.maxiters = 30
self.fig.canvas.mpl_connect('button_press_event', self.onpress)
self.fig.canvas.mpl_connect('button_release_event', self.onrelease)
self.plot_fixed_resolution(self.xmin, self.xmax,
self.ymin, self.ymax)
def mandlebrot(self, X, Y):
C = X + Y*1j
Z = C
divtime = self.maxiters + np.zeros(Z.shape, dtype=int)
for n in range(self.maxiters):
Z = Z**2 + C
diverge = Z*np.conj(Z) > 2**2
div_now = diverge & (divtime == self.maxiters)
divtime[div_now] = n
Z[diverge] = 2
return divtime
def plot_fixed_resolution(self, x1, x2, y1, y2):
x = np.linspace(x1, x2, self.resolution)
y = np.linspace(y1, y2, self.resolution)
X, Y = np.meshgrid(x, y)
C = self.mandlebrot(X, Y)
self.ax.clear()
self.ax.set_xlim(x1, x2)
self.ax.set_ylim(y1, y2)
self.ax.pcolormesh(X, Y, C)
self.fig.canvas.draw()
def onpress(self, event):
if event.button != 1: return
self.xpress = event.xdata
self.ypress = event.ydata
def onrelease(self, event):
if event.button != 1: return
self.xrelease = event.xdata
self.yrelease = event.ydata
self.xmin = min(self.xpress, self.xrelease)
self.xmax = max(self.xpress, self.xrelease)
self.ymin = min(self.ypress, self.yrelease)
self.ymax = max(self.ypress, self.yrelease)
self.plot_fixed_resolution(self.xmin, self.xmax,
self.ymin, self.ymax)
plot = ZoomPlot()
plt.show()