matplotlib tick_params在第二个y轴上无法正常工作

46scxncf  于 2023-06-23  发布在  其他
关注(0)|答案(1)|浏览(97)

我正在设计一个图形用户界面,每当我点击一个按钮,图形用户界面内的数字将被更新。该图包含两个y轴和一个公共x轴。我在matplotlib中使用twinx函数。一切都在按预期工作,除了第二个y轴的ytick。
下面是我的代码:

import sys
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from numpy import *
from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(650, 400)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButton_15 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_15.setGeometry(QtCore.QRect(430, 50, 191, 23))
        self.pushButton_15.setObjectName("pushButton_15")
        self.pushButton_15.clicked.connect(self.PlotOnCanvas)
        self.frame = QtWidgets.QFrame(self.centralwidget)
        self.frame.setGeometry(QtCore.QRect(20, 25, 421, 290))
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.frame_2 = QtWidgets.QFrame(self.frame)
        self.frame_2.setGeometry(QtCore.QRect(9, 10, 401, 271))
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth())
        self.frame_2.setSizePolicy(sizePolicy)
        self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_2.setObjectName("frame_2")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame_2)
        self.horizontalLayout_2.setObjectName("HorizontalLayout_2")
        self.figure, self.ax = plt.subplots()
        self.canvas = FigureCanvas(self.figure)
        self.horizontalLayout_2.addWidget(self.canvas)
        MainWindow.setCentralWidget(self.centralwidget)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton_15.setText(_translate("MainWindow", "test"))

    def PlotOnCanvas(self):
        self.ax.clear()
        x = np.linspace(0, 4 * pi, 1000)
        y1 = np.sin(2 * pi * np.random.rand() * 2 * x)
        y2 = np.sin(2 * pi * np.random.rand() * 2 * x)
        colory2 = 'tab:red'
        colory1 = 'tab:blue'
        ax1 = self.ax
        ax2 = ax1.twinx()
        ax1.set_xlabel('x axis', fontsize=8)
        ax1.xaxis.set_tick_params(labelsize=8)
        ax1.set_ylabel('y1 axis', color=colory1, fontsize=8)
        ax2.set_ylabel('y2 axis', color=colory2, fontsize=8)
        ax1.yaxis.set_tick_params(labelcolor=colory1, labelsize=8)
        ax2.yaxis.set_tick_params(labelcolor=colory2, labelsize=8)
        ax1.set_yticks([-1, -0.5, 0, 0.5, 1])
        ax2.set_yticks([-1, -0.5, 0, 0.5, 1])
        ax1.set_ylim(-1.2, 1.2)
        ax2.set_ylim(-1.2, 1.2)
        l1, = ax1.plot(x, y1, lw=2, color=colory1)
        l2, = ax2.plot(x, y2, lw=2, color=colory2)
        plt.legend([l1, l2], ['y1', 'y2'], fontsize=8, loc="upper right")
        plt.title('y1/y2', fontsize=8)
        plt.tight_layout()
        self.canvas.draw()
        ax2.clear()

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

这里是输出:
第1次点击后

多次点击后

第一次点击后,我可以得到两个轴的格式,我想。然而,在第二次点击之后,第二个轴开始表现得奇怪。其范围从(-1,1)到(0,1)变化;此外,它的刻度(0,0.2,...,1)开始在彼此之上打印。因此,其字体变得更粗。
我尝试使用ax.cla()和ax.clf()清除轴和两个轴,但不起作用。

huwehgph

huwehgph1#

看起来你每次点击都在创建一个新的twinx轴。在setupUi函数中,我会将self.figure, self.ax = plt.subplots()更改为self.figure, self.ax1 = plt.subplots(),然后添加一行self.ax2 = self.ax1.twinx()。这将在设置中仅使用twinx一次。
现在已经定义了这两个轴,您可以更改PlotOnCanvas函数以仅引用这两个轴。为此,您可以创建方便变量ax1 = self.ax1ax2 = self.ax2,删除ax2 = ax1.twinx(),这是在另一个函数中处理的。然后,您可以在运行函数的其余部分之前调用ax1.clear()ax2.clear()。有了这些更改,我认为它现在应该正确更新,因为它引用了正确的轴,而不是每次点击都添加一个新的twinx轴。
要解决twinx的y轴标签移动到错误的一边,请在调用ax2.set_ylabel()之前将ax2.yaxis.set_label_position("right")添加到PlotOnCanvas函数中。
综合起来我们有

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        # everything is the same until the plot creation
        # use twinx in the setup and reference the same ax2 afterward
        self.figure, self.ax1 = plt.subplots()
        self.ax2 = self.ax1.twinx()
        
        # everything else in this function is the same

    def PlotOnCanvas(self):
        # use the saved ax1 and ax2
        ax1 = self.ax1
        ax2 = self.ax2
        ax1.clear()
        ax2.clear()
        
        # other code until the axis labels
        # add this line before setting the y-label
        ax2.yaxis.set_label_position("right")
        ax2.set_ylabel('y2 axis', color=colory2, fontsize=8)

        # everything else unchanged

相关问题