PyQt嵌入MatPlotLib图形可以交互吗?

4

我有一个嵌入在GUI中的分析数据堆积条形图,我希望它更加交互性强。当用户悬停或单击某个条形时,应该显示绘图值。这可行吗?我在文档中没有找到相关内容。另外,我可以使用类似PyGal的东西,但我不知道如何将其嵌入PyQt中。任何建议都将不胜感激。

3个回答

3
最简单的解决方案是使用matplotlib事件。无论您是使用独立的绘图窗口还是嵌入GUI,它们都可以正常工作。
在matplotlib手册的event handling page中可以找到一个很好的介绍。

你知道如何将此代码与这个链接一起使用,以达到问题中描述的结果吗? - Sadie LaBounty
我首先建议您使用实际的问题描述更新您的问题。问题描述包括目标(您想要实现什么)、当前状态(为实现此目标您已经做了什么)以及问题本身(是什么阻碍了您实现目标)。一旦您完成了这些,我(或其他人)就可以提供实际的答案。 - ImportanceOfBeingErnest

1
是的,它们肯定可以。Matplotlib文档提供了一些有用的代码(https://matplotlib.org/users/event_handling.html#object-picking),您可以通过使用% matplotlib qt#tk,wx,inline#(对于笔记本电脑)等交互式方式在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真的一无所知,但是这里有一个在自定义GUI上实现上述功能的Tk实现,如果没有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()

-2
据我所知,默认情况下不行。
恐怕你需要自己动手,因为我不知道有什么常见的小部件可以做到这一点。还有其他QT设计师已经提供了更多交互式图形,比如: http://www.taurus-scada.org/en/latest/devel/designer_tutorial.html 但是,就我所记得的而言,它并没有提供你想要的功能。我建议考虑创建自己的小部件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接