matplotlib+QGraphicsView+zoom=丑陋的大像素

2024-06-07 03:57:47 发布

您现在位置:Python中文网/ 问答频道 /正文

当我放大图canvasqtagg(matplotlib QWidget)时,我会得到大的ulgy像素:

初始尺寸:

Initial size

缩放(大像素):

Zoom

红色圆圈也是一个QWidget,它不存在缩放问题。在

是否可以将FigureCanvasQTAgg显示为一个可伸缩的向量小部件?在

完整源代码:

import sys
from PyQt4 import QtGui
from PyQt4.Qt import Qt
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import numpy as np

class Circle(QtGui.QWidget):
    def __init__(self):
        super(Circle, self).__init__()
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.resize(500, 500)

    def paintEvent(self, event):
        p = QtGui.QPainter()
        p.begin(self)
        p.setPen(QtGui.QColor(255,0,0))
        p.drawEllipse(100, 100, 300, 300)
        p.end()

class MyView(QtGui.QGraphicsView):
    def __init__(self):
        QtGui.QGraphicsView.__init__(self)

        scene = QtGui.QGraphicsScene(self)
        self.scene = scene

        figure = Figure()
        axes = figure.gca()
        axes.set_title("Use the mouse wheel to zoom")
        axes.plot(np.random.rand(5))
        canvas = FigureCanvas(figure)
        canvas.setGeometry(0, 0, 500, 500)
        scene.addWidget(canvas)

        circle = Circle()
        self.circle = circle
        scene.addWidget(circle)

        self.setScene(scene)

    def wheelEvent(self, event):
        self.setTransformationAnchor(QtGui.QGraphicsView.AnchorUnderMouse)
        zoom_in = 1.15
        zoom_out = 1.0 / zoom_in
        if event.delta() > 0:
            self.scale(zoom_in, zoom_in)
        else:
            self.scale(zoom_out, zoom_out)

app = QtGui.QApplication(sys.argv)
view = MyView()
view.show()
sys.exit(app.exec_())

Tags: infromimportselfmatplotlibinitdefsys
1条回答
网友
1楼 · 发布于 2024-06-07 03:57:47

正如HYRY所说的,我非常确定matplotlib画布被渲染为位图,因此没有像素化就无法缩放。但是,您可以使用QSvgRenderer来呈现图形的svg表示。在

下面是一个基于原始代码的快速而肮脏的解决方案:

import sys
from PyQt4 import QtCore, QtGui, QtSvg
from PyQt4.Qt import Qt
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import numpy as np
import StringIO

class Circle(QtGui.QWidget):
    def __init__(self):
        super(Circle, self).__init__()
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.resize(500, 500)

    def paintEvent(self, event):
        p = QtGui.QPainter()
        p.begin(self)
        p.setPen(QtGui.QColor(255,0,0))
        p.drawEllipse(100, 100, 300, 300)
        p.end()

class MPLPlot(QtGui.QWidget):
    def __init__(self):
        super(MPLPlot, self).__init__()

        figure = Figure()
        axes = figure.gca()
        axes.set_title("Use the mouse wheel to zoom")
        axes.plot(np.random.rand(5))
        canvas = FigureCanvas(figure)
        canvas.setGeometry(0, 0, 500, 500)

        imgdata = StringIO.StringIO()
        figure.savefig(imgdata, format='svg')
        imgdata.seek(0)
        xmlreader = QtCore.QXmlStreamReader(imgdata.getvalue())
        self.renderer = QtSvg.QSvgRenderer(xmlreader)

    def paintEvent(self, event):
        p = QtGui.QPainter()
        p.begin(self)
        self.renderer.render(p)
        p.end()


class MyView(QtGui.QGraphicsView):
    def __init__(self):
        QtGui.QGraphicsView.__init__(self)

        scene = QtGui.QGraphicsScene(self)
        self.scene = scene

        plot = MPLPlot()
        scene.addWidget(plot)

        circle = Circle()
        self.circle = circle
        scene.addWidget(circle)

        self.setScene(scene)

    def wheelEvent(self, event):
        self.setTransformationAnchor(QtGui.QGraphicsView.AnchorUnderMouse)
        zoom_in = 1.15
        zoom_out = 1.0 / zoom_in
        if event.delta() > 0:
            self.scale(zoom_in, zoom_in)
        else:
            self.scale(zoom_out, zoom_out)

app = QtGui.QApplication(sys.argv)
view = MyView()
view.show()
sys.exit(app.exec_())

相关问题 更多 >