Matplotlib set axis limits在初始化时工作,但在单击按钮时不工作?

2024-09-28 19:00:35 发布

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

我正在写一个中型应用程序来查看一些数据。其结构是,绘图将保存在QTabWidget接口中,并使用绘图控制小部件来调整x限制(稍后,控制小部件中可能会有更多功能)。我在下面提供了一个最小的可复制示例。你知道吗

目前,我将图形的轴传递给我的控制小部件,并在该小部件中单击按钮后更改x限制。我已经验证了axis是否被传递给小部件(带有print语句)。我可以通过编程设置轴限制(参见第91行:自攻无花果斧在widget\uu init\uuuuuu函数中设置\u xlim(5,20000)),它可以工作,但是在button click函数中,相同的语法不起任何作用。但是,通过print语句,我验证了axis仍然被传递给button click函数。你知道吗

我很困惑,为什么set\uxlims方法在init\uuuuuu中工作,而不是在按下按钮时工作。用法:运行代码,在“X Min”和“X Max”字段中输入一个数字,单击“应用X限制”按钮。在本例中,我硬编码了按钮click axis shift以定义限制,而不是使用字段中输入的内容,但是这些字段会打印到控制台以进行调试。你知道吗

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created 
"""


import sys

from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


## import matplotlib and animation
import functools
import random as rd
import numpy as np
from numpy import array, sin, pi, arange
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import pandas as pd

## import threading
import time
from matplotlib.backends.qt_compat import QtCore, QtWidgets
from matplotlib.backends.backend_qt5agg import (FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
## New:
from PyQt5.QtWebEngineWidgets import *

######################################################8

class AppWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        self.title = 'DDBRT'
        self.setWindowTitle(self.title)

        self.DDBRT_Widget = DDBRT(self) # Call the DDBRT
        self.setCentralWidget(self.DDBRT_Widget) # set it as the central widget in the window

        self.show()
    ####
####
''' End AppWindow '''


# August 27 2019 Start building a custom QWidget that can be put into the tool in multiple instances to adjust xlims.  
# This may also serve as a templatge for other custom widgets that can go in


class XLimControlWidget(QWidget):

    def __init__(self, parent, **kwargs):
        super(QWidget, self).__init__(parent)

        # set layout:
        self.XLCWLayout = QVBoxLayout(self)
        # Insert X Min Box Label
        self.XMinSelectLbl = QLabel('Set X Min:')
        self.XLCWLayout.addWidget(self.XMinSelectLbl)
        # Insert X Min Entry Field
        self.XMinEntryField = QLineEdit('X Min')
        self.XLCWLayout.addWidget(self.XMinEntryField)
        # Insert X Max Box Label
        self.XMaxSelectLbl = QLabel('Set X Min:')
        self.XLCWLayout.addWidget(self.XMaxSelectLbl)
        # Insert X Max Box Entry Field
        self.XMaxEntryField = QLineEdit('X Max')
        self.XLCWLayout.addWidget(self.XMaxEntryField)
        # Insert Set Button
        self.SetXLimsBtn = QPushButton('Apply X Limits')
        self.XLCWLayout.addWidget(self.SetXLimsBtn)

        # Adjust layout so this widget is compact:
        self.XLCWLayout.setSpacing(0)
        self.XLCWLayout.setContentsMargins(0, 0, 0, 0)
            # Note, that doesn't actually work and it still looks ugly
            # That's annoying, but not worth figuring out how to fix right now.  
            # Need to focus on programming the behavior.

        # Try out the kwargs pass to make sure passing something works.
        for key, value in kwargs.items():
            print('%s = %s' %(key, value))
        ####

        self.Fig_ax = kwargs['Fig_ax_Key']
        print('self.Fig_ax = %s of type %s' %(self.Fig_ax, type(self.Fig_ax)))
        # Try the fig ax set xlim, which does work but doesn't.
        self.Fig_ax.set_xlim(5, 20000)

        self.SetXLimsBtn.clicked.connect(self.SetXLimsBtnClkd)
    ####    

    def SetXLimsBtnClkd(self): # Define what happens when the button is clicked.
        self.xmin = float(self.XMinEntryField.text())
        print('X Min will be ', self.xmin, ' of type ', type(self.xmin))
        self.xmax = float(self.XMaxEntryField.text())
        print('X Max will be ', self.xmax, ' of type ', type(self.xmax))
        print('self.Fig_ax = %s of type %s' %(self.Fig_ax, type(self.Fig_ax)))
        self.Fig_ax.set_xlim(20, 45)                
        # End desired goal:
        # self.Fig_ax.set_xlim(self.xmin, self.xmax)

    ####
####        


class DDBRT(QWidget):

    def __init__(self, parent):
        super(QWidget, self).__init__(parent)

        #%% Set up multithreading
        self.threadpool = QThreadPool()  # Set up QThreadPool for multithreading so the GIL doesn't freeze the GUI
        print("Multithreading with maximum %d theads" % self.threadpool.maxThreadCount())

        #%% Layout:

        ## Set layout
        self.MainLayout = QGridLayout(self)
        ## Create and embed CheckBox Placeholder
        self.ChkBx_Placeholder = QCheckBox('ChkBxPlcholdr1');
        self.MainLayout.addWidget(self.ChkBx_Placeholder, 3, 0)

        ## Create and embed tab container to hold plots, etc.
        # Initialize tab container
        self.TabsContainer = QTabWidget()

        # Initialize tabs
        self.tab0 = QWidget()

        # Add tabs
        self.TabsContainer.addTab(self.tab0, "Tab 0")


        # Populate 0th tab
        self.tab0.layout = QGridLayout(self)
        self.pushButton0 = QPushButton("PyQt5 button")
        self.tab0.layout.addWidget(self.pushButton0)
        self.tab0.setLayout(self.tab0.layout)

        # Add TabsContainer to widget
        self.MainLayout.addWidget(self.TabsContainer, 3, 1) # self.MainLayout.addWidget(self.TabsContainer, 2, 2) # Works just fine too, but I can worry about layout finessing later because it's not that difficult, important, or urgent right now
        self.setLayout(self.MainLayout)


        #%% Plot XLs (accelerations)

        XL_t = np.arange(0, 200000, 1)
        XL_X = np.sin(XL_t/20000)
        XL_Y = np.sin(XL_t/2000)
        XL_Z = np.sin(XL_t/200)


        self.tab8 =  QWidget()
        self.TabsContainer.addTab(self.tab8, "Tab 8: Acceleration mpl subplots")
        self.tab8.layout = QHBoxLayout(self)
        self.XL_Fig = Figure()

        self.XL_X_ax = self.XL_Fig.add_subplot(3, 1, 1)
        self.XL_X_ax.plot(XL_t, XL_X)
        self.XL_X_ax.set_title('Acceleration X')
#        self.XL_X_ax.grid(True)
        self.XL_X_ax.set_xlabel('Time (s)')
        self.XL_X_ax.set_ylabel('Acceleration')
#        
        self.XL_Y_ax = self.XL_Fig.add_subplot(3, 1, 2, sharex=self.XL_X_ax)
        self.XL_Y_ax.plot(XL_t, XL_Y)
        self.XL_Y_ax.set_title('Acceleration Y')
#        self.XL_Y.grid(True)
        self.XL_Y_ax.set_xlabel('Time (s)')
        self.XL_Y_ax.set_ylabel('Acceleration')
#      
        self.XL_Z_ax = self.XL_Fig.add_subplot(3, 1, 3, sharex=self.XL_X_ax)
        self.XL_Z_ax.plot(XL_t, XL_Z)
        self.XL_Z_ax.set_title('Acceleration Z')
#        self.XL_Z.grid(True)
        self.XL_Z_ax.set_xlabel('Time (s)')
        self.XL_Z_ax.set_ylabel('Acceleration')
#
        self.XL_Canvas = FigureCanvas(self.XL_Fig)
        self.XL_Canvas.print_figure('test')        

#        # Create an XLPlot container widget and add the canvas and navigation bar to it
        self.XL_PlotContainer = QWidget()
        self.XL_PlotContainer.layout = QVBoxLayout(self)
        self.XL_PlotContainer.layout.addWidget(self.XL_Canvas)
        self.XLMPLToolbar = NavigationToolbar(self.XL_Canvas, self)
        self.XL_PlotContainer.layout.addWidget(self.XLMPLToolbar, 3)
        self.XL_PlotContainer.setLayout(self.XL_PlotContainer.layout) # Looks redundant but it's needed to display the widgets        



        # add XLPlotContainer Widget to tab
        self.tab8.layout.addWidget(self.XL_PlotContainer, 1)
        self.tab8.setLayout(self.tab8.layout)


        # add XLCWidget to tab
        self.kwargs = {"Fig_ax_Key": self.XL_X_ax}
        self.XLXLCW = XLimControlWidget(self, **self.kwargs)
        self.tab8.layout.addWidget(self.XLXLCW)    
    ####
####

#%%
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = AppWindow()
    sys.exit(app.exec_())

我希望单击按钮可以更改所有子地块上的轴(因为我在设置子地块时链接了子地块),但是x限制根本不会更改。按钮单击功能不运行如print语句所示。你知道吗


Tags: thetofromimportselfinitfigax
1条回答
网友
1楼 · 发布于 2024-09-28 19:00:35

如果以后有人发现这个问题,这里有一个有效的解决方案:我将整个图形传递给我的控制小部件,使用a=自身图获取\u轴()获取我的轴列表,以及[0]。设置\u xlim(20,200);自拍图画布.draw_idle()使用单击按钮更新图形。你知道吗

相关问题 更多 >