【发布时间】:2017-08-24 04:19:59
【问题描述】:
我的 GUI 中嵌入了一个堆积的分析数据条形图,我希望它更具交互性。当用户悬停或单击条形图时,应显示绘制的值。这可以做到吗?我无法在文档中找到任何有关它的信息。或者,我可以使用 PyGal 之类的东西,但我不知道如何将它嵌入到 PyQt 中。我们将不胜感激。
【问题讨论】:
标签: python matplotlib pyqt embed pygal
我的 GUI 中嵌入了一个堆积的分析数据条形图,我希望它更具交互性。当用户悬停或单击条形图时,应显示绘制的值。这可以做到吗?我无法在文档中找到任何有关它的信息。或者,我可以使用 PyGal 之类的东西,但我不知道如何将它嵌入到 PyQt 中。我们将不胜感激。
【问题讨论】:
标签: python matplotlib pyqt embed pygal
是的,他们绝对可以。 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 中的一个实现,但在没有 picker=True 的自定义 gui 上将无法交互:
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 但是,据我记得,它不能提供你想要的东西。我宁愿考虑为您创建自己的小部件。
【讨论】:
最简单的解决方案是使用 matplotlib 事件。无论您使用独立的绘图窗口还是嵌入到 GUI 中,它们的工作方式都是一样的。
可以在 matplotlib 手册的event handling page 中找到很好的介绍。
【讨论】: