PyQt嵌入式MatPlotLib图可以是交互式的吗?



我的GUI中嵌入了一个分析数据的堆叠条形图,我希望它具有更多的交互性。当用户将鼠标悬停或单击条形图时,应显示绘制的值。这能做到吗?我无法在文档中找到有关它的任何内容。或者,我可以使用像PyGal这样的东西,但我不知道如何将其嵌入到PyQt中。如能就其中任何一项提供咨询意见,将不胜感激。

最简单的解决方案是使用 matplotlib 事件。无论您使用独立的打印窗口还是嵌入到 GUI 中,它们的工作方式都相同。

一个很好的介绍可以在matplotlib手册的事件处理页面中找到。

是的,他们绝对可以。matplotlib文档有一些有用的代码(https://matplotlib.org/users/event_handling.html#object-picking),你可以在qt,tk,wx等中以交互方式实现。使用%matplotlib qt #tk, wx, inline#(for notebook)等接口...如果你运行这段代码,我认为它的作用与你所追求的非常接近(我正在使用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.3fnsigma=%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但是,据我所知,它没有提供您想要的东西。我宁愿考虑创建您自己的小部件。

最新更新