You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib自定义axes图表保存丢失标题坐标轴的问题解决

问题根本原因
  • 散点图保存后缺失元素的问题,核心来自fig.add_axes([0,0,1,1])的参数设置:add_axes传入的四个数值是[左起始位置, 下起始位置, 轴宽度, 轴高度],以0-1的归一化坐标相对于整张画布计算尺寸。传入[0,0,1,1]会让绘图轴从画布最左下角开始,完全占满整个画布的全部宽高,原本预留用来放置标题、坐标轴标签、图例的一圈边距会被绘图轴完全覆盖。
  • Spyder IDE内显示图表时,Matplotlib交互式渲染后端会自动触发布局适配,动态将绘图轴向内收缩,为外围的标签、标题元素腾出显示空间,因此界面中能看到完整的图表内容;但调用savefig保存文件时,会严格按照手动设置的轴位置存储画布内容,不会自动调整边距,因此位于画布边界外的标签、标题、图例元素会被完全排除在保存范围外。
  • 折线图没有出现同类问题,是因为它全程使用Matplotlib的pyplot全局接口绘制,没有手动创建全铺满的自定义轴,pyplot默认会预留合理边距,保存逻辑和显示逻辑保持一致。
对应修改方案
  • 移除全铺满的轴设置:将原代码中ax=fig.add_axes([0,0,1,1])替换为默认带合理边距的子图创建方式,比如ax = fig.add_subplot(111);如果确实需要自定义轴的大小和位置,可将参数调整为[0.1, 0.1, 0.8, 0.8],主动预留10%的画布边距给外围元素。
  • 保存时自动适配元素边界:在plt.savefig()中增加参数bbox_inches='tight',该参数会在保存时自动计算所有绘图元素(含标签、标题、图例)的实际范围,避免元素被裁切。
  • 统一绘图接口逻辑:代码中存在遍历多组实验设置循环绘图的场景,尽量不要混用pyplot全局接口和手动创建的面向对象接口,将plt.title()、plt.xlabel()等全局调用替换为对应轴对象的方法(如ax.set_title()、ax.set_xlabel()),避免循环过程中出现全局状态串扰、元素错位的问题。
  • 循环绘制多图时,每次保存完成后调用plt.close(fig)关闭当前画布,避免内存泄漏和残留状态干扰下一次绘图。
修改后的可正常使用的代码
def plot_cluster_datapoints_graph(self, directory):
    fig = plt.figure()
    # 替换铺满全画布的自定义轴为默认带边距的子图
    ax = fig.add_subplot(111)
    ax.scatter(
        self.svd_data[:,0], self.svd_data[:,1],
        color='b', s=0.2, label='Datapoints'
    )
    ax.scatter(
        self.cluster_centers[:,0], self.cluster_centers[:,1],
        s=8, color='r', label='Cluster centers'
    )
    # 用轴对象的方法设置图表属性,避免全局状态串扰
    ax.set_title('Data point and clusters for 2 factors' + self.setting)
    ax.set_xlabel('Dimension 0')
    ax.set_ylabel('Dimension 1')
    ax.legend()
    ax.grid()
    # 保存时自动适配元素范围,避免裁切
    plt.savefig(
        directory + self.setting + '-CD.png',
        bbox_inches='tight'
    )
    plt.show()
    # 关闭当前画布,避免循环时状态残留
    plt.close(fig)
    return

内容的提问来源于stack exchange,提问作者Emil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.26 07:27:11