【问题标题】:Can a PyQt Embedded MatPlotLib Graph Be Interactive?PyQt 嵌入式 MatPlotLib 图形可以交互吗?
【发布时间】:2017-08-24 04:19:59
【问题描述】:

我的 GUI 中嵌入了一个堆积的分析数据条形图,我希望它更具交互性。当用户悬停或单击条形图时,应显示绘制的值。这可以做到吗?我无法在文档中找到任何有关它的信息。或者,我可以使用 PyGal 之类的东西,但我不知道如何将它嵌入到 PyQt 中。我们将不胜感激。

【问题讨论】:

    标签: python matplotlib pyqt embed pygal


    【解决方案1】:

    是的,他们绝对可以。 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()
    

    【讨论】:

      【解决方案2】:

      据我所知,默认情况下不是这样。

      我担心,你必须为自己工作一点,因为我不知道一个通​​用的小部件。还有其他 QT 设计师已经提供了更多的交互式绘图,例如: http://www.taurus-scada.org/en/latest/devel/designer_tutorial.html 但是,据我记得,它不能提供你想要的东西。我宁愿考虑为您创建自己的小部件。

      【讨论】:

        【解决方案3】:

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

        可以在 matplotlib 手册的event handling page 中找到很好的介绍。

        【讨论】:

        • 您知道如何将它与this 一起使用以达到问题中描述的结果吗?
        • 我首先建议您使用实际问题描述更新您的问题。问题描述包括目标(您想要实现的目标)、当前状态(您为实现此目标所做的工作)和问题本身(阻碍您实现目标的因素)。完成后,我(或其他人)可以提供实际答案。
        猜你喜欢
        • 2013-04-17
        • 2012-07-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-03
        • 1970-01-01
        • 2014-05-09
        • 1970-01-01
        相关资源
        最近更新 更多