如何在pyqt5应用程序中更改图的大小及其图例

时间:2020-07-31 18:13:01

标签: python matplotlib canvas pyqt5 python-3.6

我想在应用程序的一个标签中绘制一个data-frame。我正在使用python 3.6.9和PyQt5。
我从另一个answer实现了一个TabWidget。在其中一个标签中,我使用了Plotting with Matplotlib中的MplCanvas来绘制data-frame中的数据。所需课程:

class TabWidget(QtWidgets.QTabWidget):
    def __init__(self, *args, **kwargs):
        QtWidgets.QTabWidget.__init__(self, *args, **kwargs)
        self.setTabBar(TabBar(self))
        self.setTabPosition(QtWidgets.QTabWidget.West)


class MplCanvas(FigureCanvasQTAgg):

    def __init__(self, parent=None, width=6.4, height=4.8, dpi=394):
        fig = Figure(figsize= (width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)
        super(MplCanvas, self).__init__(fig)


class TabBar(QtWidgets.QTabBar):
    def tabSizeHint(self, index):
        s = QtWidgets.QTabBar.tabSizeHint(self, index)
        s.transpose()
        return s

    def paintEvent(self, event):
        painter = QtWidgets.QStylePainter(self)
        opt = QtWidgets.QStyleOptionTab()

        for i in range(self.count()):
            self.initStyleOption(opt, i)
            painter.drawControl(QtWidgets.QStyle.CE_TabBarTabShape, opt)
            painter.save()

            s = opt.rect.size()
            s.transpose()
            r = QtCore.QRect(QtCore.QPoint(), s)
            r.moveCenter(opt.rect.center())
            opt.rect = r

            c = self.tabRect(i).center()
            painter.translate(c)
            painter.rotate(90)
            painter.translate(-c)
            painter.drawControl(QtWidgets.QStyle.CE_TabBarTabLabel, opt)
            painter.restore()

应用程序的QMainWindow

class App(QMainWindow):

    def __init__(self):
        super().__init__()
        self.title = 'PLOT APP'
        self.left = 0
        self.top = 0
        self.width = 1024
        self.height = 600
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.tab_widget = MyTabWidget(self, self.width, self.height)
        self.setCentralWidget(self.tab_widget)
        self.show()

并运行该应用程序:

app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())

还有实现代码的MyTabWidget类:

class MyTabWidget(QWidget):

    def __init__(self, parent, width, height):
        super(QWidget, self).__init__(parent)
        self.layout = QVBoxLayout(self)

        # creating a tab bar
        self.tab = TabWidget()

        self.new_df = self.prepare_data()

        self.layout_gauges = QHBoxLayout(self)

        self.layout_plot = QVBoxLayout(self)

        self.canvas = MplCanvas(self, width=10, height=8, dpi=100)
        self.toolbar = NavigationToolbar(self.canvas, self)
        self.comboBox = QtWidgets.QComboBox(self)

        # widgets associated with tab
        self.graphs_tab = QWidget()

        # assigning tab to tab-bar
        self.tab.addTab(self.graphs_tab, "Graphs")


        # graphs tab
        self.graphs_tab.layout = QVBoxLayout(self)

        self.layout_combobox_time_filter = QHBoxLayout(self)
        self.layout_combobox = QHBoxLayout(self)

        self.draw_graphs()
        self.graphs_tab.setLayout(self.graphs_tab.layout)

        self.layout.addWidget(self.tab)
        self.setLayout(self.layout)

        self.tab.resize(300, self.ertefa)
        self.tab.show()

        def draw_graphs(self):

            for item in self.new_df.columns[1:]:
                self.comboBox.addItem(str(item))
            self.comboBox.setMaximumWidth(200)

            self.comboBox.activated[str].connect(self.draw_plot)

            self.layout_combobox.addWidget(self.comboBox)
            self.layout_combobox.setAlignment(QtCore.Qt.AlignRight)
            self.layout_combobox_time_filter.addLayout(self.layout_combobox.layout())

            self.canvas.axes.plot(self.new_df.index, self.new_df.loc[:, self.comboBox.currentText()])
            self.label = self.canvas.axes.set_xlabel('Time', fontsize=9)
            self.label = self.canvas.axes.set_ylabel(self.comboBox.currentText(), fontsize=9)
            self.canvas.axes.legend(str(self.comboBox.currentText()))
            self.canvas.draw()

            self.graphs_tab.layout.addWidget(self.toolbar)
            self.graphs_tab.layout.addWidget(self.canvas)
            self.graphs_tab.layout.addLayout(self.layout_combobox_time_filter.layout())

    def draw_plot(self):

        self.canvas.axes.plot(self.new_df.index, self.new_df.loc[:, self.comboBox.currentText()])
        self.label = self.canvas.axes.set_xlabel('Time', fontsize=9)
        self.label = self.canvas.axes.set_ylabel(self.comboBox.currentText(), fontsize=9)
        self.canvas.axes.legend(self.comboBox.currentText())
        self.canvas.draw()

    def prepare_data(self):
        # extract data from file
        sensor = pd.read_excel("file.xlsx")
        return  df_new

widthheight的默认值为(width=6.4, height=4.8),基于documentation

我的屏幕尺寸为1024 * 600像素。然后,按如下所示创建此类的实例,并为其分配一个NavigationToolbar

self.canvas = MplCanvas(self, width=10, height=7, dpi=100)
self.toolbar = NavigationToolbar(self.canvas, self)

我按如下所示绘制数据框:

self.canvas.axes.plot(self.new_df.index, self.new_df.loc[:, self.comboBox.currentText()])
self.label = self.canvas.axes.set_xlabel('Time', fontsize=9)
self.label = self.canvas.axes.set_ylabel(self.comboBox.currentText(), fontsize=9)
self.canvas.axes.legend(str(self.comboBox.currentText()))
self.canvas.draw()

但是每次我更改画布的widthheight时,尺寸都不会改变。 我的代码或对此的理解有什么问题?

enter image description here

图的图例并没有完全显示,如图所示,仅显示了图例的第一个字符。如何解决?


好的,我发现了问题。在初始化MplCanvas对象的fig中,应将tight_layout属性设置为True

MplCanvas(FigureCanvasQTAgg)类:

def __init__(self, parent=None, width=6.4, height=4.8, dpi=394):
    fig = Figure(figsize= (width, height), dpi=dpi, tight_layout=True)
    self.axes = fig.add_subplot(111)
    super(MplCanvas, self).__init__(fig)

但图例仅显示一个字符。

0 个答案:

没有答案