Seaborn中的非透明置信区间

3

背景:
我想提交论文的期刊只接受 .tiff(不支持 LaTeX),.jpg(不适合图形)和 .eps(不支持 alpha 透明度,除非将图像转换为光栅图,这会导致文件大小巨大)。我的许多绘图使用 seaborn 的 regplot,它绘制透明的置信区间。是否可能在不完全手动重新制作所有图形的情况下绘制不透明的置信区间(例如作为虚线或背景中的实色)?

示例:

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

sns.set_style("ticks")
np.random.seed(0)
n = 50

fig, ax = plt.subplots(figsize=(8,6))

x = np.random.randn(n)
y1 = np.random.randn(n)
y2 = np.random.randn(n)

sns.regplot(x, y1, ax=ax)
sns.regplot(x, y2, ax=ax)

plt.show()

具有重叠透明置信区间的regplot示例

最简单/最好的方法是将此文件保存为.eps文件,而不会丢失重叠置信区间的信息。

1个回答

4
问题在于需要透明度来显示两个置信区间的重叠部分。需要将图像光栅化处理。
如果期刊接受,使用jpg格式实际上并不成问题。您可以通过控制图像质量来进行调整。
plt.savefig(__file__+".jpg", quality=95)

使用eps也是可能的,这里,可以仅对置信区间fill_between-曲线进行栅格化,而不是对所有内容进行栅格化。优点是轴、标签和点仍然是矢量图形,在不同的缩放级别下不会出现像素化。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import PolyCollection as p
import seaborn as sns

sns.set_style("ticks")
np.random.seed(0)
n = 50

fig, ax = plt.subplots(figsize=(8,6))

x = np.random.randn(n)
y1 = np.random.randn(n)
y2 = np.random.randn(n)

sns.regplot(x, y1, ax=ax)
sns.regplot(x, y2, ax=ax)

plt.savefig(__file__+".jpg", quality=95)
for c in ax.findobj(p):
    c.set_zorder(-1)
    c.set_rasterized(True)
#everything on zorder -1 or lower will be rasterized
ax.set_rasterization_zorder(0)

plt.savefig(__file__+".eps")
plt.savefig(__file__+".png")
plt.show()

最终的eps文件如下图所示:
enter image description here 尽管文件大小稍微大了一些,但我不确定这是否是一个真正的问题。

哦,我不知道你只能栅格化图像的部分。这很棒。谢谢!期刊对文件大小要求非常严格,这就是为什么我不想使用大多数未压缩的JPG。在最初的提交中,我使用了一个解决方法,即将seaborn源代码中的fill_between部分替换为虚线,但是你的解决方案看起来更加优雅。 - Fred S
1
PS 为什么要比较类型的字符串表示而不是使用 isinstance?另外,我认为 matplotlib 的轴有一个返回给定类型所有艺术家的函数,但我忘记它叫什么了。 - mwaskom
1
@mwaskom 你所说的函数叫做ax.findobj。我只是太懒了,从输出中复制了str repr。但现在我已经改变了。关于jpg,当然不是理想的选择,但如果jpg的质量足够高,与png之间几乎没有什么区别。无论期刊的要求是否合理,你都需要遵守它们的要求。 - ImportanceOfBeingErnest

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接