python - 如何在 tkinter 中删除 matplot 行?
问题描述
我正在尝试制作绘制熊猫数据框(tkinter,matplotlib)的GUI程序
但是分配按钮命令有一些问题
我想要的是在单击按钮时使一行可见/不可见,
起初我尝试使用 for 循环分配按钮,这样我就不需要关心行数
但是当我单击按钮时,只有最后一行会切换状态
所以我打破了循环并在没有循环的情况下分配,并检查了它是否有效。
我怎样才能使第一种方法有效?
import numpy as np
import matplotlib.pyplot as plt
import tkinter as tk
from tkinter import ttk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
# Sample Data
x = np.arange(100)
y1 = np.sin(x)
y2 = np.cos(x)
data = pd.DataFrame()
data['time'] = x
data['sin'] = y1
data['cos'] = y2
class graph():
def __init__(self):
self.win = tk.Tk()
# Graph region
self.frame1 = ttk.LabelFrame(self.win,text='Figure')
self.frame1.grid(row=0,column=0,columnspan=2)
self.fig,self.ax = plt.subplots()
self.canvas = FigureCanvasTkAgg(self.fig,master=self.frame1)
self.canvas.get_tk_widget().grid(row=0,column=0)
self._read_data(data)
# Make buttons using for loop
# it doesn't work!!
self.frame2= ttk.LabelFrame(self.win,text='graph handle')
self.frame2.grid(row=1,column=0)
for i,col in enumerate(self.pic_dic.keys()):
ttk.Label(self.frame2,text=col).grid(row=i,column=0)
ttk.Button(self.frame2,text='on/off Graph',command=lambda:self._onoff_pic(col)).grid(row=i,column=1)
# Make buttons using without loop
# but it works!!
self.frame3= ttk.LabelFrame(self.win,text='graph handle (without for loop)')
self.frame3.grid(row=1,column=1)
ttk.Label(self.frame3,text='time').grid(row=0,column=0)
ttk.Button(self.frame3,text='on/off',command=lambda:self._onoff_pic('time')).grid(row=0,column=1)
ttk.Label(self.frame3,text='sin').grid(row=1,column=0)
ttk.Button(self.frame3,text='on/off',command=lambda:self._onoff_pic('sin')).grid(row=1,column=1)
ttk.Label(self.frame3,text='cos').grid(row=2,column=0)
ttk.Button(self.frame3,text='on/off',command=lambda:self._onoff_pic('cos')).grid(row=2,column=1)
self.canvas.draw()
def _read_data(self,data):
self.pic_dic = {}
for col in data.columns:
self.pic_dic[col] = {}
self.pic_dic[col]['line'], = self.ax.plot(data['time'],data[col])
def _onoff_pic(self,col):
tmp = self.pic_dic[col]['line'].get_visible()
self.pic_dic[col]['line'].set_visible(not tmp)
self.canvas.draw()
a = graph()
a.win.mainloop()
a.win.quit()
感谢!
解决方案
在您的代码中:
for i,col in enumerate(self.pic_dic.keys()):
ttk.Label(self.frame2,text=col).grid(row=i,column=0)
ttk.Button(self.frame2,text='on/off Graph',command=lambda:self._onoff_pic(col)).grid(row=i,column=1)
的值col
将被赋予 for 循环后最后一次迭代的值。因此,当单击按钮时调用 lambda 时,col
将使用最终值。
您需要在 lambda 中使用参数的默认值:
for i, col in enumerate(self.pic_dic.keys()):
ttk.Label(self.frame2, text=col).grid(row=i, column=0)
ttk.Button(self.frame2, text='on/off Graph', command=lambda c=col: self._onoff_pic(c)).grid(row=i,column=1)
参数的默认值将在创建 lambda 时初始化。
推荐阅读
- c# - 如何获取动态对象名称 WPF
- google-cloud-platform - 将 SSH 密钥传输到 VM。( SSH 不适用于实例)
- sql-server - 如何让我的 SQL Server 数据库与我在 Azure 上部署的 REST API 一起工作?
- serverless-framework - DynamoDB 和无服务器:未授权执行:dynamodb:Query on resource
- javascript - ChartJS 每个数据集/独立数据集的单独标签?
- css - 如何在悬停时更改引导程序 4 导航栏切换器的颜色?
- macos - 如何在macOS上使用pf重写传入数据包的接口?
- rust - 将使用的变量保存在向量中
- r - 从 svykm(Lumley 的调查包)中提取样本方差以进行复杂的调查分析
- python - 如何使用 Bleach 完全删除 HTML 中的链接?