1. 当前位置:网站首页 > Pyqt

matplotlib内嵌放大镜效果


内嵌放大镜效果

  • 在网页中这种效果可以很好的找到,找了网上一圈都没找到适合自己的,干脆自己写了一个,废话不多说,看下面效果
    效果

实现代码

  • 我这里主要是内嵌入到Pysdie6中
# coding=utf-8
import sys
import re
import time
from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout,\
    QPushButton, QListWidget, QInputDialog, QListWidgetItem, QAbstractItemView, QToolBar,\
    QMessageBox, QDockWidget, QLabel, QVBoxLayout, QTableWidget, QTableWidgetItem, QStatusBar, QTextBrowser,\
    QSizePolicy
from PySide6.QtGui import QIcon, QAction
from PySide6.QtCore import QSize, Qt, QThread, Signal
from qt_material import apply_stylesheet
import matplotlib
import mplcyberpunk
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
from pylab import mpl

matplotlib.use("Qt5Agg")
plt.style.use('cyberpunk')
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False

class Chart(FigureCanvas):
    """这是一个窗口部件,即QWidget(当然也是FigureCanvasAgg)"""

    def __init__(self, parent=None, width=5, height=4, dpi=100, main=None):
        Figure(figsize=(width, height), dpi=dpi)
        fig, self.axes = plt.subplots()
        # self.compute_initial_figure()
        FigureCanvas.__init__(self, fig)
        self.setParent(parent)
        FigureCanvas.setSizePolicy(self,
                                   QSizePolicy.Expanding,
                                   QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)
        mplcyberpunk.add_glow_effects()
        plt.ylabel('Value', fontsize=10)
        plt.xlabel('Time', fontsize=10)
        plt.tight_layout()
        # 头部标签
        # self.toolbarFFT = NavigationToolbar(self)
        # main.addWidget(self.toolbarFFT)
        # 子图
        # ax:父坐标系
        # width, height:子坐标系的宽度和高度(百分比形式或者浮点数个数)
        # loc:子坐标系的位置
        # bbox_to_anchor:边界框,四元数组(x0, y0, width, height) 设置位置
        # bbox_transform:从父坐标系到子坐标系的几何映射
        # axins:子坐标系

        self.ax_inner = inset_axes(self.axes, width='30%', height='25%', loc='lower right', borderpad=0,
                                   bbox_to_anchor=(0, 0.05, 1, 1), bbox_transform=self.axes.transAxes)
        # 添加放大框
        self.rectangle = matplotlib.patches.Rectangle((0, 0), 20, 100, linewidth=1, edgecolor='r', facecolor='none')
        self.axes.add_artist(self.rectangle)
        self.move_state = False
        self.canvas = fig
        self.ax_inner.set_xlim(xmin=0, xmax=20)
        self.ax_inner.set_ylim(ymin=0, ymax=100)
        # 事件
        fig.canvas.mpl_connect('button_press_event', self.press)
        fig.canvas.mpl_connect('button_release_event', self.release)
        fig.canvas.mpl_connect('motion_notify_event', self.notify)

    def press(self, event):
        if self.rectangle.contains_point((event.x, event.y)):
            # 点击了矩形框
            self.move_state = True

    def release(self, event):
        self.move_state = False
        self.ax_inner.set_xlim(xmin=self.rectangle.xy[0], xmax=self.rectangle.xy[0] + 20)
        self.ax_inner.set_ylim(ymin=self.rectangle.xy[1], ymax=self.rectangle.xy[1] + 100)
        self.canvas.canvas.draw()

    def notify(self, event):
        if self.move_state and event.xdata is not None and  event.ydata is not None:
            self.rectangle.xy = (event.xdata, event.ydata)
            self.canvas.canvas.draw()

class ChartCanvas(Chart):
    """画布"""
    def __init__(self, *args, **kwargs):
        Chart.__init__(self, *args, **kwargs)
        plt.ylabel('Value', fontsize=10)
        plt.xlabel('Time', fontsize=10)
        self.axes.set_ylim(ymin=-300, ymax=300)
        self.axes.set_xlim(xmin=-0, xmax=100)
        self.axes.xaxis.set_major_formatter(DateFormatter('%H:%M:%S'))
        self.ax_inner.xaxis.set_major_formatter(DateFormatter('%M:%S'))

class AppMain(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('测试')
        self.resize(1400, 800)
        self.setMinimumSize(1400, 800)
        # 中心控件
        self.center_widget = QWidget()
        # 中心控件布局
        self.center_widget_layout = QVBoxLayout()
        # 将布放置到中心控件上
        self.center_widget.setLayout(self.center_widget_layout)
        # 将中心控件放置到主窗口内
        self.setCentralWidget(self.center_widget)
        self.chart_widget = QWidget()
        self.view = ChartCanvas(self.chart_widget, width=5, height=4, dpi=100, main=self.center_widget_layout)
        self.tab2ui()

    def tab2ui(self):
        self.center_widget_layout.addWidget(self.view)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    apply_stylesheet(app, theme='dark_teal.xml')
    windows = AppMain()
    windows.show()
    sys.exit(app.exec())

本文最后更新于2023-3-7,已超过 3个月没有更新,如果文章内容或图片资源失效,请留言反馈,我们会及时处理,谢谢!
版权说明

本文地址:http://www.liuyangdeboke.cn/?post=38
未标注转载均为本站远程,转载请注明文章出处:

发表评论

联系我们

在线咨询:点击这里给我发消息

微信号:17721538135

工作日:9:00-23:00,节假日休息

扫码关注