如何在PyQt5中动态更新seaborn热图且不重复生成colorbar
解决方案
问题原因
每次调用sns.heatmap()时,默认会自动在画布上新建一个colorbar轴,你只清空了热图的主绘图轴,之前生成的colorbar轴还残留在画布上,所以多次更新后就会出现多个重复的colorbar。
方案1:复用固定colorbar轴(最小改动现有代码)
步骤1:修改mplwidget.py的初始化逻辑,提前预留热图和colorbar的专属轴
class MplWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.canvas = FigureCanvas(Figure()) self.plot = None self.cbar_ax = None # 存储colorbar的专属轴 vertical_layout = QVBoxLayout() vertical_layout.addWidget(self.canvas) # 划分画布区域:90%给热图,10%给colorbar gs = self.canvas.figure.add_gridspec(1, 2, width_ratios=[9, 1]) self.axes = self.canvas.figure.add_subplot(gs[0]) self.cbar_ax = self.canvas.figure.add_subplot(gs[1]) self.setLayout(vertical_layout) self.canvas.toolbar = NavigationToolbar(self.canvas, self) self.layout().addWidget(self.canvas.toolbar) self.layout().addWidget(self.canvas) X = np.random.randn(10, 8) self.plot = sns.heatmap(X, cmap='PuBu', square=True, linewidth=0.1, linecolor=(0.1, 0.2, 0.2), ax=self.axes, cbar_ax=self.cbar_ax, vmin=np.min(X), vmax=np.max(X))
步骤2:修改MainPresenter.py的更新逻辑,绘制时指定复用预留的colorbar轴
def matrixPlot(self, selected): X = np.random.randn(10,8) self.view.MplWidget.axes.clear() self.view.MplWidget.plot = sns.heatmap(X, cmap='PuBu', square=True, linewidth=0.1, linecolor=(0.1, 0.2, 0.2), ax=self.view.MplWidget.axes, cbar_ax=self.view.MplWidget.cbar_ax, vmin=np.min(X), vmax=np.max(X)) self.view.MplWidget.canvas.draw()
方案2:直接更新热图数据(性能更优,无重复创建对象的开销)
不需要每次重新调用sns.heatmap,直接修改已有热图对象的矩阵数据,colorbar会自动同步更新,不需要修改初始化代码:
def matrixPlot(self, selected): X = np.random.randn(10,8) # 直接更新热图数据 self.view.MplWidget.plot.collections[0].set_array(X.ravel()) # 同步更新数值范围(如果你的新数据值域固定可以省略这两行) self.view.MplWidget.plot.collections[0].set_clim(vmin=np.min(X), vmax=np.max(X)) # 重绘画布 self.view.MplWidget.canvas.draw()
内容的提问来源于stack exchange,提问作者Victor Y.
相关产品推荐
相关产品推荐

