自定义Matplotlib Figure类中rcParams无法生效的解决咨询
问题:Matplotlib自定义Figure类中rcParams不生效的解决办法
我尝试基于matplotlib.figure.Figure编写自定义图形类,以自动应用正确格式,但rcParams无论放在代码的哪个位置(甚至类定义之前)都无法生效。当前代码如下:
import matplotlib from matplotlib.axes import Axes from matplotlib.figure import Figure from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as Canvas class CustomFigure(Figure): def __init__(self, figsize: tuple, layout: str): super().__init__(figsize=figsize, layout=layout) self.canvas = Canvas(self) matplotlib.use("QtAgg") self.set_common_params() def generate_axes(self, num_axes: int, layout: tuple = None) -> Axes: if layout is None: layout = (1, num_axes) return self.subplots(*layout) def set_common_params(self): matplotlib.rcParams["figure.titlesize"] = 45 matplotlib.rcParams["axes.titlesize"] = 13 matplotlib.rcParams["axes.labelsize"] = 12 matplotlib.rcParams["axes.linewidth"] = 1.5 matplotlib.rcParams["xtick.labelsize"] = 11 matplotlib.rcParams["ytick.labelsize"] = 11 @staticmethod def set_labels(ax: Axes, xlabel: str, ylabel: str, title: str = None): ax.set_xlabel(xlabel) ax.set_ylabel(ylabel) if title is not None: ax.set_title(title) def generate_pdf(self, filename: str): self.savefig(f"{filename}.pdf") if __name__ == "__main__": import sys from PySide6.QtWidgets import QApplication, QMainWindow app = QApplication(sys.argv) win = QMainWindow() fig = CustomFigure((5,5), "tight") fig.set_labels(fig.generate_axes(1), "X", "Y", "Title") win.setCentralWidget(fig.canvas) win.show() sys.exit(app.exec())
解决方案
1. 提前设置Matplotlib后端
matplotlib.use("QtAgg")必须在任何Matplotlib组件初始化之前调用,不能放在CustomFigure的__init__方法中。将其移到文件最开头,导入Matplotlib后立即执行:
import matplotlib matplotlib.use("QtAgg") # 移到此处 from matplotlib.axes import Axes from matplotlib.figure import Figure from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as Canvas
2. 在Figure初始化前设置rcParams
rcParams是全局配置,仅对之后创建的Matplotlib对象生效。当前代码中set_common_params在super().__init__之后调用,此时Figure已经创建,配置无法应用到当前实例。修改__init__方法,先设置rcParams再初始化父类:
def __init__(self, figsize: tuple, layout: str): self.set_common_params() # 先设置全局配置 super().__init__(figsize=figsize, layout=layout) # 再初始化Figure self.canvas = Canvas(self)
修改后的完整代码
import matplotlib matplotlib.use("QtAgg") from matplotlib.axes import Axes from matplotlib.figure import Figure from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as Canvas class CustomFigure(Figure): def __init__(self, figsize: tuple, layout: str): self.set_common_params() super().__init__(figsize=figsize, layout=layout) self.canvas = Canvas(self) def generate_axes(self, num_axes: int, layout: tuple = None) -> Axes: if layout is None: layout = (1, num_axes) return self.subplots(*layout) def set_common_params(self): matplotlib.rcParams["figure.titlesize"] = 45 matplotlib.rcParams["axes.titlesize"] = 13 matplotlib.rcParams["axes.labelsize"] = 12 matplotlib.rcParams["axes.linewidth"] = 1.5 matplotlib.rcParams["xtick.labelsize"] = 11 matplotlib.rcParams["ytick.labelsize"] = 11 @staticmethod def set_labels(ax: Axes, xlabel: str, ylabel: str, title: str = None): ax.set_xlabel(xlabel) ax.set_ylabel(ylabel) if title is not None: ax.set_title(title) def generate_pdf(self, filename: str): self.savefig(f"{filename}.pdf") if __name__ == "__main__": import sys from PySide6.QtWidgets import QApplication, QMainWindow app = QApplication(sys.argv) win = QMainWindow() fig = CustomFigure((5,5), "tight") ax = fig.generate_axes(1) fig.set_labels(ax, "X", "Y", "Title") win.setCentralWidget(fig.canvas) win.show() sys.exit(app.exec())
额外优化
原测试代码中fig.set_labels(fig.generate_axes(1), ...)会重复创建Axes(generate_axes每次调用都会生成新的子图),建议先保存Axes实例再调用set_labels,避免不必要的资源消耗(如上述修改后的代码所示)。
内容的提问来源于stack exchange,提问作者ohshitgorillas
相关产品推荐
相关产品推荐

