我想在应用程序的一个标签中绘制一个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
width
和height
的默认值为(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()
但是每次我更改画布的width
和height
时,尺寸都不会改变。
我的代码或对此的理解有什么问题?
图的图例并没有完全显示,如图所示,仅显示了图例的第一个字符。如何解决?
好的,我发现了问题。在初始化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)
但图例仅显示一个字符。