Seaborn图表中字体大小的精细控制

69

我目前正在尝试使用Seaborn为我的学术论文创建图表。这些图表看起来很棒并且易于生成,但是我遇到的一个问题是在图表中对字体大小进行精细控制有些困难。

我的论文中字体大小为9pt,我希望确保我的图表中的字体大小为9pt或10pt。但是在Seaborn中,字体大小主要通过字体比例sns.set_context("paper", font_scale=0.9)控制。因此,除了通过尝试和错误来确定正确的字体大小之外,我很难找到合适的字体大小。是否有更有效的方法来解决这个问题呢?

我还想确保不同Seaborn图之间的字体大小是一致的。但是,并非所有的Seaborn图都具有相同的尺寸,因此似乎在所有图中使用相同的字体比例并不能在这些不同的图之间创建相同的字体大小?

下面是我的代码。我希望能够对双栏学术论文的图表格式进行控制,而不会扭曲字体大小或图表。我使用Latex撰写我的论文。

# Seaborn setting                                                                                                                                              
sns.set(style='whitegrid', rc={"grid.linewidth": 0.1})
sns.set_context("paper", font_scale=0.9)                                                  
plt.figure(figsize=(3.1, 3)) # Two column paper. Each column is about 3.15 inch wide.                                                                                                                                                                                                                                 
color = sns.color_palette("Set2", 6)

# Create a box plot for my data                                                      
splot = sns.boxplot(data=df, palette=color, whis=np.inf,                              
        width=0.5, linewidth = 0.7)

# Labels and clean up on the plot                                                                                                                                                                                                                                                                                              
splot.set_ylabel('Normalized WS')                                                     
plt.xticks(rotation=90)                                                               
plt.tight_layout()                                                                    
splot.yaxis.grid(True, clip_on=False)                                                 
sns.despine(left=True, bottom=True)                                                   
plt.savefig('test.pdf', bbox_inches='tight')                                          

1
我不太确定你在这里的问题是什么。您可以为各种与字体相关的rc参数提供字体大小以更改默认值,并且您可以将字体大小传递给任何特定的绘图函数,以指定创建的元素的字体。font_scale并不是唯一的方法,它只是一种方便的同时更改许多东西的方式。 - mwaskom
不回答这个问题,但也许可以考虑一种基本的方法变化:看看 psfrag 包。它允许您用字符串替换图中的字符。 - Schorsch
1
@mawskom,你回答了我的问题--通过rc指定字体大小。但是我认为在seaborn中一个很好的功能是能够指定一个应用于所有字体属性的font_size。因为使用rc,我必须分别设置每个字体参数(例如,axes.labelsize,legend.fontsize)。 - kc2uno
3个回答

123

你是正确的,这个问题的文档说明很糟糕。但是你可以在构建图表后直接更改字体大小参数(而不是字体比例)。请参考以下示例:

import seaborn as sns
import matplotlib.pyplot as plt
tips = sns.load_dataset("tips")

b = sns.boxplot(x=tips["total_bill"])
b.axes.set_title("Title",fontsize=50)
b.set_xlabel("X Label",fontsize=30)
b.set_ylabel("Y Label",fontsize=20)
b.tick_params(labelsize=5)
plt.show()

这导致了这样的结果:

不同标签的不同字体大小

为了使图表之间一致,我认为您只需要确保 DPI 相同即可。另外,也有可能通过自定义rc 字典来稍微定制“font.size”参数,但我不太确定如何做。

注意:我也不太明白为什么他们更改了轴标签和刻度的字体大小变量的名称。看起来有点不直观。


那么刻度大小呢?如果我们手动设置字体大小,而不使用font_scale,则轴刻度不会随着图形大小的变化而自适应。就像上面的图中,您可以看到x轴和y轴刻度有多小。如果有人能告诉如何增加刻度大小,那将非常有帮助。 - Madhura Pande

47

这还不够令人满意,不是吗?我发现在设置上下文时最简单的方法是:

sns.set_context("paper", rc={"font.size":8,"axes.titlesize":8,"axes.labelsize":5})   

这应该能够满足90%的标准绘图需求。如果您想要比轴标签更小的刻度标签,请将 'axes.labelsize' 设置为较小的(刻度标签)值,并手动指定轴标签(或其他自定义元素),例如:
axs.set_ylabel('mylabel',size=6)

你可以将其定义为一个函数并在脚本中加载,这样你就不必记住你的标准数字,或者每次都调用它。
def set_pubfig:
    sns.set_context("paper", rc={"font.size":8,"axes.titlesize":8,"axes.labelsize":5})   

当然,您可以使用 配置文件,但我想整个想法是拥有一个简单,直接的方法,这就是为什么上面的方法很好的原因。
注意:如果您指定了这些数字,则在所有指定的字体元素上,即使您设置了它,sns.set_context 中的 font_scale 也会被忽略。

6
对于出版级别的图片(未被要求,因此不是答案的一部分),有一个额外的提示:您可以使用 plt.figure 指定 dpi,但无法在 plt.subplots 中指定,因此您必须在保存时指定它 plt.savefig(filename,dpi=500)参考链接)。 - TNT
5
这是我使用的代码:def defaultPlotting(): sns.set(rc={'figure.figsize':(11.7,8.27),"font.size":20,"axes.titlesize":20,"axes.labelsize":20},style="white") - David C.
如果这种方法不起作用,请检查您是否在sns.set_context()语句之后没有sns.set()语句。即使您在set()方法中没有指定任何字体更改,它似乎至少部分地重置了它们。 - problemofficer - n.f. Monica

0

我刚刚花了太长时间尝试找出“纸张”sns上下文的实际值。我只能找到“talk”的值,老实说我很生气!我就打算使用

sns.set_context("paper", rc{"font.size":8,"axes.titlesize":8,"axes.labelsize":5})  

即使这些可能是任何值!!!


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