PyQt嵌入式MatPlotLib图可以互动吗?

问题描述 投票:1回答:3

我有一个嵌入在我的GUI中的分析数据的堆积条形图,我希望它更具互动性。当用户悬停或点击栏时,应显示绘制的值。可以这样做吗?我在文档中找不到任何相关内容。或者我可以使用像PyGal这样的东西,但我不知道如何将它嵌入到PyQt中。对任何一方的建议将不胜感激。

python matplotlib pyqt embed pygal
3个回答
1
投票

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

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


1
投票

是的,他们绝对可以。 matplotlib文档有一些有用的代码(https://matplotlib.org/users/event_handling.html#object-picking),您可以通过使用%matplotlib qt #tk, wx, inline#(for notebook)等在qt,tk,wx等界面中以交互方式实现...如果您运行此代码,我认为它做得非常接近你所追求的是什么(我正在使用tk ...所以改为qt,我想它仍然可以工作)。运行它,然后单击散点图上的一个点以触发事件“onpick”并显示“point”历史记录:

"""
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()

-1
投票

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

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

热门问题
推荐问题
最新问题