我有一個FigureCanvasQTAgg創建圖,用戶選擇要繪制的資料,畫布通過呼叫self.fig.clear()和創建新圖來更新圖。這作業正常,但我遇到了問題。我設計了一個在軸下帶有注釋的圖,但是每次更新圖形時,圖都會變得越來越小。這段代碼復制了這個問題:
import sys
from PyQt5 import QtCore, QtWidgets
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
class MplCanvas(FigureCanvasQTAgg):
def __init__(self, parent=None, width=5, height=4, dpi=100):
self.fig, self.axes = plt.subplots(figsize=(width, height), dpi=dpi, tight_layout=True)
super(MplCanvas, self).__init__(self.fig)
def make_plot(self, x, y, fmt='.k'):
self.fig.clear()
axes = self.fig.subplots()
axes.plot(x, y, fmt)
axes.invert_yaxis()
axes.annotate('I make the plot get smaller and smaller', xy=(0,0), xycoords='figure points', fontsize='x-small', fontstyle='italic', annotation_clip=False)
self.draw()
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
#Create a layout with central alignment
self.layout1 = QtWidgets.QVBoxLayout()
self.layout1.setAlignment(QtCore.Qt.AlignCenter)
# Create a placeholder widget to hold our toolbar and canvas.
self.widget1 = QtWidgets.QWidget()
self.widget1.setLayout(self.layout1)
self.setCentralWidget(self.widget1)
#Create a matplotlib canvas and add it to the layout
self.sc = MplCanvas(self, width=5, height=4, dpi=100)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed)
self.sc.setSizePolicy(sizePolicy)
self.layout1.addWidget(self.sc)
# Create a button
self.button = QtWidgets.QPushButton()
self.button.setText("Press me")
self.layout1.addWidget(self.button)
#Create the connection
self.button.clicked.connect(self.plot_something)
self.show()
def plot_something(self):
print('plotting')
x = [0,1,2,3,4]
y = [10,1,20,3,40]
self.sc.make_plot(x, y)
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
app.exec_()
在這個例子中,擺弄xycoords引數有時可以解決它,例如使用xycoords='axes points'或'data'似乎有效。但這并不能解決我實際應用中的問題。禁用緊布局似乎也解決了它,但由于各種原因我需要緊布局。
軸每次變得越來越小這一事實表明這self.fig.clear()實際上并沒有清除所有內容 - 在繪圖的迭代之間會記住一些東西。有沒有辦法可以完全清除無花果物件并開始一個新物件?或者最好每次都關閉實際畫布并創建一個新畫布?
uj5u.com熱心網友回復:
當 Artist 參與 tiny_layout(或更好的 constrained_layout)時,它會嘗試使軸足夠小,以免與其他軸重疊。在這種情況下,您在軸上放置注釋,但在圖形坐標中繪制它。在這種情況下,最好將其從自動布局中取出:
an = axes.annotate('I make the plot get smaller and smaller',
xy=(0,0), xycoords='figure points',
fontsize='x-small', fontstyle='italic',
annotation_clip=False)
an.set_in_layout(False)
至于為什么Axes變得越來越小,tight_layout使用subplots_adjust,它設定了Figure.subplotpars。這些并沒有被歸零Fig.clear()。你實際上可以打開一個關于這個的錯誤報告,因為我認為它們應該被重置。
但是,對于您的代碼,我可能不會一直清除該數字,因為就 CPU 周期而言,這會變得很昂貴。如果可能,最好更新 Axes 中的資料。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/381773.html
