PYTHON-使用 xarray 的方法进行绘图时,从 tkinter 中的嵌入图形中删除颜色条

问题描述 投票:0回答:1

我目前正在实现一个简单的 GUI,用于显示 Netcdf 内容以及一些其他用途,但是我遇到了一个看起来比以前更简单的问题:如何删除由

xarray
数据集创建的颜色条?

我想做的事情如下:

  • 创建一个嵌入 tkinter 框架的图形并在其中显示一些数据
  • 可以自由绘制一个变量或另一个变量

一切顺利,直到我开始绘制 2D 变量(参见下面的示例,变量

d2
),xarray 会自动创建一个颜色条来匹配绘图(这是所需的效果),但是我不知道如何删除这个颜色条当切换回显示另一个变量时。这会导致颜色条仍在图中,并且当我们切换回显示示例中的
d1
时,会在第一个颜色条旁边创建一个新的颜色条。

因此,有没有一种方法可以访问包含 xarray 创建的颜色条的轴并将其删除,或者访问颜色条本身并将其删除?

import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
import numpy as np
import tkinter as tk
import xarray as xr

class MainFrame(tk.Frame):
    def __init__(self, master, ds):
        # dummy data
        self.ds = ds
        self.plt_displayed = 'd1'
        
        self.parent = master
        tk.Frame.__init__(self, self.parent, bg='turquoise', borderwidth=1, relief="sunken")
        self.create_layout()
        
        # Protocol
        self.parent.protocol("WM_DELETE_WINDOW", self.window_closure_handler)
        
    def window_closure_handler(self):
        self.parent.quit()
        self.parent.destroy()

    def create_layout(self):
        # Setting up the button
        click_me = tk.Button(self, text='Click Me!', command=self.bind_button_click_me)
        
        # Seting up the ploting area
        self.make_background_figure()
        self.canvas = FigureCanvasTkAgg(self.fig, master=self)
        self.canvas.draw()
        
        toolbar = NavigationToolbar2Tk(self.canvas, self, pack_toolbar=True)
        toolbar.update()
        
        # Setting up the geometry
        toolbar.pack(side=tk.BOTTOM, fill=tk.X)
        plot_widget = self.canvas.get_tk_widget()
        plot_widget.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        click_me.pack()
    
    def refresh_canvas(self):
        self.axs.cla()
        self.make_background_figure()
        self.canvas.draw()    
    
    def make_background_figure(self):
        if not hasattr(self, 'fig'):
            self.fig, self.axs = plt.subplots(figsize=(5,4), dpi=100)
        self.ds['d1'].plot(ax=self.axs)
        self.axs.set(title='This 1D data!')
        self.axs.grid()
        
    def plt_d2(self):
        self.ds['d2'].plot(ax=self.axs)
        self.axs.set(title='This 2D data!')
        self.canvas.draw()
        
    def bind_button_click_me(self):
        if self.plt_displayed == 'd1':
            self.plt_d2()
            self.plt_displayed = 'd2'
        else:
            self.refresh_canvas()
            self.plt_displayed = 'd1'
             
    
def main():
    # Creating some dummy data
    x = np.arange(0, 100, 0.1)
    y = np.flip(x)
    d1 = np.sin(2*np.pi*x/15)
    d2 = d1[:, None] * np.cos(2*np.pi*y/15)[None, :]
    
    ds = xr.Dataset(
        data_vars=dict(d1=(["x"], d1), d2=(["y", "x"], d2)),
        coords=dict(x=("x", x), y=("y", y))
        )
        
    root = tk.Tk()
    
    window = MainFrame(root, ds)
    window.pack(side='top', fill='both', expand=True)
    
    root.mainloop()
            

if __name__ == '__main__':
    main()

补充说明:

  • 我知道,可以直接绕过 xarray 的绘图方法并使用
    matplotlib
    代替,但 xarray 的绘图方法已经实现,让我提供一个符合 CF 的数据集来自动管理图形标签
  • 虽然可以销毁包含该图形的小部件并创建一个新的小部件,但我想知道是否可以使用新绘图简单地“刷新”该图形

我正在使用:

  • xarray -> 2024.3.0
  • matplotlib -> 3.8.4
  • tkinter -> 8.6.14
python-3.x matplotlib tkinter python-xarray
1个回答
0
投票

感谢 Stef 的回答,它给了我一个研究的方向。根据您的答案,我开始研究如何通过使用

fig.axes[-1]
调用它来删除包含颜色条的斧头,但虽然可以完成,但它也会在颜色条容器所在的位置留下一个空白空间。

与其盲目地一次又一次地删除轴,我得出的结论是,最好清除整个图形,只重新定义我需要的轴。以下是我为适应我的目的而更改的原始部分:

def make_background_figure(self):
    if not hasattr(self, 'fig'):
        self.fig, self.axs = plt.subplots(figsize=(5,4), dpi=100)
    
    elif len(self.fig.axes) > 1:
        self.fig.clf()
        self.axs = self.fig.add_subplot(1,1,1)
        
    self.ds['d1'].plot(ax=self.axs)
    self.axs.set(title='This 1D data!')
    self.axs.grid()

唯一的区别是

elif
条件允许我检查是否存在 colobar,在这种情况下,图形将被清除,并创建一个新的子图来替换刚刚被
fig.clf()

删除的子图
© www.soinside.com 2019 - 2024. All rights reserved.