让PySide与matplotlib配合使用的方法

24

我已经尝试运行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)

我正在构建一个简单的科学数据记录器,最终将用于商业应用,因此我确实需要PySide的LGPL许可和绘图功能。有人有经验如何使其正常工作或替代绘图软件包或想法吗?
提前感谢。

1
尝试跳过示例代码,使用最新的matplotlib git tip 进行尝试。https://github.com/matplotlib/matplotlib (请注意,您需要安装各种构建依赖项。这不是纯Python。)大约一个月前,qt后端添加了完整的PySide支持,但尚未发布。你喜欢的代码只是一种解决方法。更新版本的matplotlib将完全支持pyside。 - Joe Kington
3个回答

33

在示例http://www.scipy.org/Cookbook/Matplotlib/PySide中,为什么要使用`import pylab`?没有这行也可以正常工作。 - JuanPablo
2
@JuanPablo 不需要导入pylab,但我认为在实际导入pylab或pyplot之前,尽可能地配置Matplotlib是必要的...祝好运! - dsign

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)

在Qt Designer中,我创建了一个空白小部件来容纳我的图表,然后当我初始化主窗口时,我调用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)

然后根据需要调用 plotDataPoints:
def plotDataPoints(self,x,y):        
    self.DataPlot.axes.clear()
    self.DataPlot.axes.plot(x,y,'bo-')
    self.DataPlot.draw()

注意:每次都要清除并重新绘制整个图表(因为我的数据形状不断变化),因此速度较慢。

2

我认为你可能已经在matplotlib邮件列表上发布了这篇文章,但是以防其他人正在寻找答案。最好的选择是使用Github上的主分支,但是如果您不会或不知道如何使用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_()

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