让PySide与matplotlib一起使用

jbb*_*med 21 python matplotlib pyside

我试过在SciPy网站上运行示例代码,但是我收到此错误:

Traceback (most recent call last):
  File ".\matplotlibPySide.py", line 24, in <module>
    win.setCentralWidget(canvas)
TypeError: 'PySide.QtGui.QMainWindow.setCentralWidget' called with wrong argument types:
  PySide.QtGui.QMainWindow.setCentralWidget(FigureCanvasQTAgg)
Supported signatures:
  PySide.QtGui.QMainWindow.setCentralWidget(PySide.QtGui.QWidget)
Run Code Online (Sandbox Code Playgroud)

我正在构建一个简单的科学数据记录器,最终将用于商业应用程序,所以我真的需要PySide的LGPL和绘图功能.有没有人有如何使这个工作或替代绘图包或想法的经验?

提前致谢.

dsi*_*ign 31

你提到的例子:

http://www.scipy.org/Cookbook/Matplotlib/PySide

有效,但您可能需要建议使用PySide:

...
matplotlib.use('Qt4Agg')
matplotlib.rcParams['backend.qt4']='PySide'
import pylab
...
Run Code Online (Sandbox Code Playgroud)

  • @JuanPablo无需导入pylab,但我认为你需要在实际导入pylab或pyplot之前尽可能多地配置Matplotlib ... suerte! (2认同)

小智 5

我有类似的目标(LGPL,潜在的商业用途),这就是我最终让它发挥作用的方式.

创建一个matplotlib小部件(有关PyQt的详细信息,请参见此处):

import matplotlib

matplotlib.use('Qt4Agg')
matplotlib.rcParams['backend.qt4']='PySide'

from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas

class MatplotlibWidget(FigureCanvas):

    def __init__(self, parent=None,xlabel='x',ylabel='y',title='Title'):
        super(MatplotlibWidget, self).__init__(Figure())

        self.setParent(parent)
        self.figure = Figure()
        self.canvas = FigureCanvas(self.figure)
        self.axes = self.figure.add_subplot(111)

        self.axes.set_xlabel(xlabel)
        self.axes.set_ylabel(ylabel)
        self.axes.set_title(title)
Run Code Online (Sandbox Code Playgroud)

在Qt Designer中我创建了一个空白小部件来保存我的情节,然后当我__init__在主窗口中调用setupPlot时:

def  setupPlot(self):
    # create a matplotlib widget
    self.DataPlot = MatplotlibWidget()
    # create a layout inside the blank widget and add the matplotlib widget        
    layout = QtGui.QVBoxLayout(self.ui.widget_PlotArea)        
    layout.addWidget(self.DataPlot,1)
Run Code Online (Sandbox Code Playgroud)

然后我根据需要调用plotDataPoints:

def plotDataPoints(self,x,y):        
    self.DataPlot.axes.clear()
    self.DataPlot.axes.plot(x,y,'bo-')
    self.DataPlot.draw()
Run Code Online (Sandbox Code Playgroud)

注意:这会清除并重新绘制整个绘图(因为我的数据形状不断变化)因此并不快.


Ger*_*ald 2

我想您可能已将其发布在 matplotlib 邮件列表上。但以防万一其他人正在寻找答案。最好的选择是使用 Github 上的 master 分支,但如果您不能或不知道如何使用 Github 版本,您可以使用以下代码在 PySide 中渲染绘图。

import numpy as np
from matplotlib import use
use('AGG')
from matplotlib.transforms import Bbox
from matplotlib.path import Path
from matplotlib.patches import Rectangle
from matplotlib.pylab import *
from PySide import QtCore,QtGui

rect = Rectangle((-1, -1), 2, 2, facecolor="#aaaaaa")
gca().add_patch(rect)
bbox = Bbox.from_bounds(-1, -1, 2, 2)

for i in range(12):
    vertices = (np.random.random((4, 2)) - 0.5) * 6.0
    vertices = np.ma.masked_array(vertices, [[False, False], [True, True], [False, False], [False, False]])
    path = Path(vertices)
    if path.intersects_bbox(bbox):
        color = 'r'
    else:
        color = 'b'
    plot(vertices[:,0], vertices[:,1], color=color)

app = QtGui.QApplication(sys.argv)
gcf().canvas.draw()

stringBuffer = gcf().canvas.buffer_rgba(0,0)
l, b, w, h = gcf().bbox.bounds

qImage = QtGui.QImage(stringBuffer, 
                      w,
                      h,
                      QtGui.QImage.Format_ARGB32)

scene = QtGui.QGraphicsScene()
view = QtGui.QGraphicsView(scene)
pixmap = QtGui.QPixmap.fromImage(qImage)
pixmapItem = QtGui.QGraphicsPixmapItem(pixmap)
scene.addItem(pixmapItem)
view.show()

app.exec_()
Run Code Online (Sandbox Code Playgroud)