我的 GUI 中嵌入了一个堆积的分析数据条形图,我希望它更具交互性。当用户悬停或单击条形图时,应显示绘制的值。这可以做到吗?我无法在文档中找到任何有关它的信息。或者,我可以使用 PyGal 之类的东西,但我不知道如何将它嵌入到 PyQt 中。对任何一个的建议将不胜感激。
3 回答
最简单的解决方案是使用 matplotlib 事件。无论您使用独立的绘图窗口还是嵌入到 GUI 中,它们的工作方式都是一样的。
可以在 matplotlib 手册的事件处理页面中找到一个很好的介绍。
是的,他们绝对可以。matplotlib 文档有一些有用的代码(https://matplotlib.org/users/event_handling.html#object-picking%matplotlib qt #tk, wx, inline#(for notebook)
),您可以使用等以交互方式在 qt、tk、wx 等界面中实现这些代码。 ..如果您运行此代码,我认为它所做的事情与您所追求的非常接近(我正在使用 tk ......所以更改为 qt,我想它仍然可以工作)。运行它,然后单击散点图上的一个点以触发事件“onpick”并显示该“点”历史记录:
"""
compute the mean and stddev of 100 data sets and plot mean vs stddev.
When you click on one of the mu, sigma points, plot the raw data from
the dataset that generated the mean and stddev
"""
import numpy as np
import matplotlib.pyplot as plt
%matplotlib tk
X = np.random.rand(100, 1000)
xs = np.mean(X, axis=1)
ys = np.std(X, axis=1)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_title('click on point to plot time series')
line, = ax.plot(xs, ys, 'o', picker=5) # 5 points tolerance
def onpick(event):
if event.artist!=line: return True
N = len(event.ind)
if not N: return True
figi = plt.figure()
for subplotnum, dataind in enumerate(event.ind):
ax = figi.add_subplot(N,1,subplotnum+1)
ax.plot(X[dataind])
ax.text(0.05, 0.9, 'mu=%1.3f\nsigma=%1.3f'%(xs[dataind], ys[dataind]),
transform=ax.transAxes, va='top')
ax.set_ylim(-0.5, 1.5)
figi.show()
return True
fig.canvas.mpl_connect('pick_event', onpick)
plt.show()
我对 qt 没有太多经验,但是对于 tk,您似乎可以将 matplotlib 图形发送到画布上并且它们工作得很好 - 所以我认为在 qt 中可能有类似的东西,但根据您的问题,您已经有它嵌入并且就在交互之后。
抬头我遇到了一个需要一段时间才能弄清楚的问题,我不知道它在 qt 中是否相同(也许其他人可以确认)......但只是抬头,你可能需要picker=True
在绘图时明确设置. 同样,我对 qt 真的一无所知,但这是上述 tk 中的一个实现,但是在自定义 gui 上,没有picker=True
它就不会是交互式的:
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import Tkinter as tk #for Python 3.x use import tkinter as tk
import ttk #for Python 3.x use from tkinter import ttk
class My_GUI:
def __init__(self,master):
self.master=master
master.title("samplegui")
f = Figure(figsize=(5,5), dpi=100)
a = f.add_subplot(111)
a.scatter(np.random.normal(size=100),np.random.normal(size=100),picker=True)
canvas1=FigureCanvasTkAgg(f,master)
canvas1.show()
canvas1.get_tk_widget().pack(side="top",fill='x',expand=True)
f.canvas.mpl_connect('pick_event',self.onpick)
toolbar=NavigationToolbar2TkAgg(canvas1,master)
toolbar.update()
toolbar.pack(side='top',fill='x')
def onpick(self,event):
#do stuff
print "My OnPick Event Worked!"
return True
root=tk.Tk()
gui=My_GUI(root)
root.mainloop()
据我所知,不是默认的。
我担心,你必须为自己工作一点,因为我不知道一个通用的小部件。还有其他 QT 设计师已经提供了更多的交互式绘图,例如: http ://www.taurus-scada.org/en/latest/devel/designer_tutorial.html 但是,据我所知,它没有提供您想要的. 我宁愿考虑为您创建自己的小部件。