我已经matplotlib嵌入到我正在开发的应用程序中PyQt4。问题是当我动态地向图形中添加子图时,图形会随着每个添加的子图而压缩。我以为可以通过将图形设置为来解决这个问题,QScrollArea但这并不奏效(据我所知)。以下是我认为可行的示例
matplotlib
PyQt4
QScrollArea
import os os.environ['QT_API'] = 'pyside' from PySide.QtGui import * from PySide.QtCore import * import matplotlib from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg from matplotlib.figure import Figure class Canvas(FigureCanvasQTAgg): def __init__(self, parent=None): self.figure = Figure() super(Canvas, self).__init__(self.figure) ax = self.figure.add_subplot(1,1,1) ax.plot([1,2,3]) self.draw() def add_subplot(self, data=[]): rows = len(self.figure.axes) + 1 for index, axes in enumerate(self.figure.axes, start=1): axes.change_geometry(rows, 1, index) ax = self.figure.add_subplot(rows, 1, index+1) ax.plot(data) self.draw() class Main(QWidget): def __init__(self, parent=None): super(Main, self).__init__(parent) self.canvas = QScrollArea(self) self.canvas.setWidget(Canvas(self)) self.canvas.setWidgetResizable(True) for x in range(5): self.canvas.widget().add_subplot() layout = QVBoxLayout(self) layout.addWidget(self.canvas) app = QApplication([]) main = Main() main.show() app.exec_()
注意到所有图表是如何组合在一起以在同一个可见空间中显示的吗?我不想滚动查看其他图表。我不确定具体该怎么做。
有人知道该怎么做或者用其他方法做吗?
您遇到的问题是因为您在动态添加子图时并没有管理图形的大小,导致所有子图被压缩并堆叠在一起。如果您希望每个子图能够显示并且不被压缩,可以考虑以下几种方法:
使用QScrollArea作为容器,但需要正确管理图表的尺寸。这意味着您需要确保每次添加子图时,容器能够适应所有图形的大小。
管理子图的布局,例如让子图适应窗口的大小,并且按合适的比例来显示。
您可以通过设置FigureCanvas的大小,确保在添加每个子图时,每个子图有足够的空间来显示,或者使用QVBoxLayout或者QGridLayout来组织子图,而不是仅依赖QScrollArea。
FigureCanvas
QVBoxLayout
QGridLayout
下面是一个示例,其中通过QVBoxLayout来添加多个子图,并调整每个子图的大小:
import os os.environ['QT_API'] = 'pyside' from PySide.QtGui import * from PySide.QtCore import * import matplotlib from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg from matplotlib.figure import Figure class Canvas(FigureCanvasQTAgg): def __init__(self, parent=None): self.figure = Figure(figsize=(5, 4)) # 设置默认图形大小 super(Canvas, self).__init__(self.figure) self.layout = QVBoxLayout() # 布局管理器,用来管理子图 self.setLayout(self.layout) def add_subplot(self, data=[]): ax = self.figure.add_subplot(len(self.figure.axes)+1, 1, len(self.figure.axes)+1) ax.plot(data) ax.set_title(f"Subplot {len(self.figure.axes)}") # 更新canvas并重新绘制 self.draw() class Main(QWidget): def __init__(self, parent=None): super(Main, self).__init__(parent) self.canvas = Canvas(self) # 向canvas中添加5个子图 for x in range(5): self.canvas.add_subplot([x, x + 1, x + 2]) layout = QVBoxLayout(self) layout.addWidget(self.canvas) self.setLayout(layout) app = QApplication([]) main = Main() main.show() app.exec_()
Canvas的构造函数:
Canvas
add_subplot方法:
add_subplot
Figure
self.draw()
设置每个子图的标题: 这样可以更容易地知道每个子图的位置,并帮助调试。
通过这种方式,您避免了QScrollArea导致的图形压缩问题,同时也确保了每个子图能够正常显示。