我尝试执行以下步骤:
1. 插入值对列表 [xmin, xmax]
2. 创建跨度对象的初始列表
3. 绘制跨度并将标签写入列表框
4. 将跨度添加到绘图(通过 onlick事件)并更新列表框
5. 删除和突出显示跨度
这是一个示例代码:
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from matplotlib.widgets import SpanSelector
import tkinter as tk
import numpy as np
class App:
def __init__(self, master, l_val_pair):
# Create a container
frame = tk.Frame(master)
# Create fields
self.button_left = tk.Button(frame,text="Export")
self.button_left.pack(side="left")
self.button_right = tk.Button(frame,text="Delete", command =
lambda: self.delete(self.l_spans))
self.button_right.pack(side="left")
self.listbox = tk.Listbox(master)
self.listbox.pack(side='bottom', fill=tk.X)
#define figure
self.fig = Figure()
self.ax = self.fig.add_subplot(111)
#sample data for a line
self.x = np.arange(0.0, 5.0, 0.01)
self.y = np.sin(2*np.pi*self.x) + 0.5*np.random.randn(len(self.x))
#plot line and list of spans
self.ax.plot(self.x,self.y)
self.l_spans = [self.ax.axes.axvspan(
val_pair[0],val_pair[1], facecolor='red', alpha=0.3, label=val_pair)
for val_pair in l_val_pair]
#create a listbox
[self.listbox.insert(tk.END, item.get_label()) for item in self.l_spans]
self.listbox.bind('<<ListboxSelect>>', self.highlight_span)
#plot figure
self.canvas = FigureCanvasTkAgg(self.fig,master=master)
self.canvas.show()
self.canvas.get_tk_widget().pack(side='top', fill='both', expand=1)
frame.pack()
#use span selector
self.span = SpanSelector(self.ax, self.sel_span, 'horizontal', useblit=True,
rectprops=dict(alpha=0.5, facecolor='red'), span_stays=False)
#connect
self.canvas.mpl_connect('key_press_event', self.span)
def sel_span(self,xmin, xmax):
indmin, indmax = np.searchsorted(self.x, (xmin, xmax))
indmax = min(len(self.x) - 1, indmax)
span = self.ax.axes.axvspan(xmin=self.x[indmin], xmax=self.x[indmax],
alpha = 0.5, facecolor='red')
#add actual span to list of spans
self.l_spans.append(span)
#update view (spans and listbox) with central list of spans
self.update_view()
def update_view(self):
#clear visualisation
self.listbox.delete(0,tk.END)
[span.remove() for span in self.l_spans]
#fill with new data
[self.listbox.insert(tk.END, span.get_label()) for span in self.l_spans]
[span.draw(self.ax) for span in self.l_spans] #HERE IS THE PROBLEM!!!
#update view
#...
def highlight_span():
pass
def delete(self,item):
pass
list_vals= [[1,2],[2.5,4]]
root = tk.Tk()
app = App(root, list_vals)
root.mainloop()
函数 update_view 中的问题:
我需要插入 span.draw() 的渲染器是什么?
我不确定我的方法是否很好,因为我没有使用 tkinter 的经验。你怎么看?