Matplotlib 保存图像时的背景色透明度

11 投票
1 回答
24045 浏览
提问于 2025-04-18 11:56

之前有个问题讨论了如何使用 savefig() 来保存和屏幕上显示的背景颜色(也就是面色)一样的图像,具体内容可以查看这里:

fig = plt.figure()
fig.patch.set_facecolor('blue')
fig.savefig('foo.png', facecolor=fig.get_facecolor())

Matplotlib 图形的面色(背景颜色)

(使用 savefig() 时,我们需要重新指定背景颜色。)

我还可以设置透明度,比如:如何设置 Matplotlib 图表背景颜色的透明度

fig.patch.set_alpha(0.5)

我找不到一种方法可以让图像的透明背景色保存成屏幕上显示的样子。文档上似乎没有详细说明这个问题:http://matplotlib.org/faq/howto_faq.html#save-transparent-figures - 实际保存的效果没有显示出来。使用 transparent=Truesavefig() 并不能达到让背景色透明的效果,反而似乎让除了坐标轴和图例以外的所有东西都变得透明,包括图表的背景。

编辑:一些相关的代码片段:

def set_face_color(fig, facecolor):
    if facecolor is False:
        # Not all graphs get color-coding
        facecolor = fig.get_facecolor()
        alpha = 1
    else:
        alpha = 0.5
    color_with_alpha = colorConverter.to_rgba(
        facecolor, alpha)
    fig.patch.set_facecolor(color_with_alpha)

def save_and_show(plt, fig, save, disp_on, save_as):
    if save:
        plt.savefig(save_as, dpi=dpi_file, facecolor=fig.get_facecolor(),
                    edgecolor='none')
    if disp_on is True:
        figManager = plt.get_current_fig_manager()
        figManager.window.showMaximized()
        plt.show()
    else:
        plt.close('all')

可能可以把这些结合起来,但我通常在绘图函数开始时调用 set_face_color(),然后再构建子图网格,最后在结束时调用 save_and_show()。我想这两个地方都应该可以工作,但我更希望能把这些功能分开,并能够从最终的图像中提取透明度值,以便传递给 savefig()

编辑 2 - 一图胜千言

左边的透明度为 0.5,右边为 1。

image of code below

t = [1, 2, 3, 4, 5]
fig = plt.figure()
fig.patch.set_alpha(0.5)
fig.set_facecolor('b')
plt.plot(t, t)
fig2 = plt.figure()
fig2.set_facecolor('b')
plt.plot(t,t)

1 个回答

5

我在Matplotlib 1.5上运行了你的代码,发现它产生了预期的输出。为了避免将来出现类似问题,我在下面提供了两种简单的方法来解决这个问题。

先说一句,你绝对不想在保存图像时设置 transparent=True,因为这会覆盖面颜色,具体可以参考matplotlib.figure.savefig的源代码

要真正解决你的问题,你发的第二个链接 如何设置Matplotlib图表背景颜色的透明度 实际上解决了这个问题。问题在于你代码片段中使用了 fig.set_facecolor,而应该使用 fig.patch.set_facecolor

解决方案 1:

从上面提到的问题中,使用保存图像时的面颜色参数。

import matplotlib.pyplot as plt

fig = plt.figure()
fig.patch.set_facecolor('b') # instead of fig.patch.set_facecolor
fig.patch.set_alpha(0.5)

plt.plot([1,3], [1,3])
plt.tight_layout()
plt.show()
plt.savefig('method1.png', facecolor=fig.get_facecolor())

解决方案 2:

你也可以通过rcParams来指定保存图像时的面颜色。

import matplotlib.pyplot as plt
import matplotlib as mpl

fig = plt.figure()

col = 'blue'
#specify color of plot when showing in program. 
#fig.set_facecolor(col) also works
fig.patch.set_facecolor(col)
#specify color of background in saved figure
mpl.rcParams['savefig.facecolor'] = col 

#set the alpha for both plot in program and saved image
fig.patch.set_alpha(0.5)
plt.plot([1,3], [1,3])
plt.tight_layout()
plt.show()
plt.savefig('method2.png')

如果你希望你的坐标轴有一个背景,这些解决方案应该能保持那个背景(比如Erotemic的评论中提到的seaborn产生的背景)不变。如果你想更明确一点,可以添加:

ax.patch.set_color('palegoldenrod') # or whatever color you like
ax.patch.set_alpha(.7)

坐标轴的透明度会自动应用到保存的图像中,无需额外操作。

请注意,在这两种情况下,我都使用了 plt.tight_layout() 来消除保存图像时多余的空白。你可以在matplotlib的文档中了解更多信息。

撰写回答