matplotlib.backends.backend_qt5agg.FigureCanvasQTagg构成及用法
程序员文章站
2022-05-28 12:36:35
...
matplotlib:一个绘图用的Python模块
backends:matplotlib中的一个模块,后端。
backend_qt5agg:backends里面的一个模块,里面有两个类:FigureCanvasQTAgg
和_BackendQT5Agg
FigureCanvasQTagg:backend_qt5agg里的一个类
matplotlib绘制的图可以应用在PyQt5应用里面,下面三个import都需要:
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
**matplotlib.backends.backend_qt5agg用来连接Matplotlib和PyQt5。**backend_qt5agg.py的原文如下:
"""
Render to qt from agg.
"""
import ctypes
from matplotlib.transforms import Bbox
from .. import cbook
from .backend_agg import FigureCanvasAgg
from .backend_qt5 import (
QtCore, QtGui, QtWidgets, _BackendQT5, FigureCanvasQT, FigureManagerQT,
NavigationToolbar2QT, backend_version)
from .qt_compat import QT_API
class FigureCanvasQTAgg(FigureCanvasAgg, FigureCanvasQT):
def __init__(self, figure):
# Must pass 'figure' as kwarg to Qt base class.
super().__init__(figure=figure)
def paintEvent(self, event):
"""Copy the image from the Agg canvas to the qt.drawable.
In Qt, all drawing should be done inside of here when a widget is
shown onscreen.
"""
if self._update_dpi():
# The dpi update triggered its own paintEvent.
return
self._draw_idle() # Only does something if a draw is pending.
# If the canvas does not have a renderer, then give up and wait for
# FigureCanvasAgg.draw(self) to be called.
if not hasattr(self, 'renderer'):
return
painter = QtGui.QPainter(self)
rect = event.rect()
left = rect.left()
top = rect.top()
width = rect.width()
height = rect.height()
# See documentation of QRect: bottom() and right() are off by 1, so use
# left() + width() and top() + height().
bbox = Bbox(
[[left, self.renderer.height - (top + height * self._dpi_ratio)],
[left + width * self._dpi_ratio, self.renderer.height - top]])
reg = self.copy_from_bbox(bbox)
buf = cbook._unmultiplied_rgba8888_to_premultiplied_argb32(
memoryview(reg))
# clear the widget canvas
painter.eraseRect(rect)
qimage = QtGui.QImage(buf, buf.shape[1], buf.shape[0],
QtGui.QImage.Format_ARGB32_Premultiplied)
if hasattr(qimage, 'setDevicePixelRatio'):
# Not available on Qt4 or some older Qt5.
qimage.setDevicePixelRatio(self._dpi_ratio)
origin = QtCore.QPoint(left, top)
painter.drawImage(origin / self._dpi_ratio, qimage)
# Adjust the buf reference count to work around a memory
# leak bug in QImage under PySide on Python 3.
if QT_API in ('PySide', 'PySide2'):
ctypes.c_long.from_address(id(buf)).value = 1
self._draw_rect_callback(painter)
painter.end()
def blit(self, bbox=None):
"""Blit the region in bbox.
"""
# If bbox is None, blit the entire canvas. Otherwise
# blit only the area defined by the bbox.
if bbox is None and self.figure:
bbox = self.figure.bbox
# repaint uses logical pixels, not physical pixels like the renderer.
l, b, w, h = [pt / self._dpi_ratio for pt in bbox.bounds]
t = b + h
self.repaint(l, self.renderer.height / self._dpi_ratio - t, w, h)
def print_figure(self, *args, **kwargs):
super().print_figure(*args, **kwargs)
self.draw()
@_BackendQT5.export
class _BackendQT5Agg(_BackendQT5):
FigureCanvas = FigureCanvasQTAgg