我正在使用matplotlib创建一个交互式3D图,并且在添加功能性颜色条时遇到了一些困难。我给了颜色条自己的轴,这样它就不会随着3D网格旋转。初始图和颜色条正确生成,但是,在第一次与滑块交互时,颜色条消失。在下一次交互时,绘制的数据也消失。这似乎是由于cb.remove()命令。如果cb.remove()命令不存在,则颜色条将在每次交互时简单地绘制自己,使图中有许多杂乱的颜色条堆叠在一起。我创建了colorbar作为它自己的对象,它应该在每个更新的滑块值上重新生成,所以我不太明白为什么它不会重新生成,或者为什么它也会删除绘制的数据。
下面是一些代码来重现这个问题。
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button
import matplotlib.cm as cm
from matplotlib.colors import Normalize
import numpy as np
%matplotlib notebook
class InteractivePlot:
def __init__(self):
self.fig = plt.figure(layout='constrained')
self.ax = self.fig.add_subplot(111, projection='3d')
#initalize plot
self.cmap = cm.get_cmap('Blues')
x = np.random.randint(1, 3, size=(4, 4))
normalizer=Normalize(np.min(x),np.max(x))
im=cm.ScalarMappable(norm=normalizer, cmap=self.cmap)
self.cax_pos = [0.93, 0.15, 0.02, 0.7] # left, bottom, width, height
self.cax = self.fig.add_axes(self.cax_pos)
self.cb = self.fig.colorbar(im, cax=self.cax)
self.X, self.Y = np.meshgrid(np.linspace(0,1,x.shape[1]), np.linspace(0,1,x.shape[0]))
self.ax.contourf(x, self.X, self.Y, offset=0, cmap=self.cmap)
#Create buttons to increment and decrement iteration slider
self.button1 = Button(plt.axes([0.85, 0.01, 0.05, 0.05]), '-', hovercolor='white')
self.button2 = Button(plt.axes([0.9, 0.01, 0.05, 0.05]), '+', hovercolor='white')
slider_ax = plt.axes([0.15, 0.01, 0.6, 0.03])
self.slider = Slider(slider_ax, 'Upper lim', 1, 10, valinit=3, valstep=1)
self.slider.on_changed(self.update)
self.button1.on_clicked(self.update)
self.button2.on_clicked(self.update)
def update(self, val):
self.ax.clear()
self.cb.remove()
def increment_slider(event):
self.slider.set_val(self.slider.val + self.slider.valstep)
def decrement_slider(event):
self.slider.set_val(self.slider.val - self.slider.valstep)
self.button1.on_clicked(decrement_slider)
self.button2.on_clicked(increment_slider)
self.x = np.random.randint(1, self.slider.val, size=(4, 4))
normalizer=Normalize(np.min(self.x),np.max(self.x))
im=cm.ScalarMappable(norm=normalizer, cmap=self.cmap)
self.ax.contourf(self.x, self.X, self.Y, offset=0, zdirs='z', cmap=self.cmap)
self.cb = self.fig.colorbar(im, cax=self.cax)
self.fig.canvas.draw_idle()
plt.show()
1条答案
按热度按时间vql8enpb1#
我已经解决了这个问题,但将离开这个情况下,其他人有类似的问题。由于某些原因,将colorbar轴初始化到类会在从update函数调用它们时导致此问题。相反,您必须在更新函数中独立定义轴及其位置。我不确定调用self.cax是否会导致这个问题,但这里有一些更新的代码,可以按预期工作