简体   繁体   English

如何更改 matplotlib 图上的字体大小

[英]How to change the font size on a matplotlib plot

How does one change the font size for all elements (ticks, labels, title) on a matplotlib plot?如何更改 matplotlib 图上所有元素(刻度、标签、标题)的字体大小?

I know how to change the tick label sizes, this is done with:我知道如何更改刻度标签大小,这是通过以下方式完成的:

import matplotlib 
matplotlib.rc('xtick', labelsize=20) 
matplotlib.rc('ytick', labelsize=20) 

But how does one change the rest?但是如何改变其余的呢?

From the matplotlib documentation ,matplotlib 文档中,

font = {'family' : 'normal',
        'weight' : 'bold',
        'size'   : 22}

matplotlib.rc('font', **font)

This sets the font of all items to the font specified by the kwargs object, font .这会将所有项目的字体设置为 kwargs 对象 font 指定的font

Alternatively, you could also use the rcParams update method as suggested in this answer :或者,您也可以使用此答案中建议的rcParams update方法:

matplotlib.rcParams.update({'font.size': 22})

or或者

import matplotlib.pyplot as plt
plt.rcParams.update({'font.size': 22})

You can find a full list of available properties on the Customizing matplotlib page .您可以在自定义 matplotlib 页面上找到可用属性的完整列表。

If you are a control freak like me, you may want to explicitly set all your font sizes:如果您像我一样是控制狂,您可能需要明确设置所有字体大小:

import matplotlib.pyplot as plt

SMALL_SIZE = 8
MEDIUM_SIZE = 10
BIGGER_SIZE = 12

plt.rc('font', size=SMALL_SIZE)          # controls default text sizes
plt.rc('axes', titlesize=SMALL_SIZE)     # fontsize of the axes title
plt.rc('axes', labelsize=MEDIUM_SIZE)    # fontsize of the x and y labels
plt.rc('xtick', labelsize=SMALL_SIZE)    # fontsize of the tick labels
plt.rc('ytick', labelsize=SMALL_SIZE)    # fontsize of the tick labels
plt.rc('legend', fontsize=SMALL_SIZE)    # legend fontsize
plt.rc('figure', titlesize=BIGGER_SIZE)  # fontsize of the figure title

Note that you can also set the sizes calling the rc method on matplotlib :请注意,您还可以在matplotlib上调用rc方法设置大小:

import matplotlib

SMALL_SIZE = 8
matplotlib.rc('font', size=SMALL_SIZE)
matplotlib.rc('axes', titlesize=SMALL_SIZE)

# and so on ...

If you want to change the fontsize for just a specific plot that has already been created, try this:如果您只想更改已创建的特定绘图的字体大小,请尝试以下操作:

import matplotlib.pyplot as plt

ax = plt.subplot(111, xlabel='x', ylabel='y', title='title')
for item in ([ax.title, ax.xaxis.label, ax.yaxis.label] +
             ax.get_xticklabels() + ax.get_yticklabels()):
    item.set_fontsize(20)
matplotlib.rcParams.update({'font.size': 22})

Update: See the bottom of the answer for a slightly better way of doing it.更新:请参阅答案的底部以获得更好的方法。
Update #2: I've figured out changing legend title fonts too.更新#2:我也想出了改变图例标题字体。
Update #3: There is a bug in Matplotlib 2.0.0 that's causing tick labels for logarithmic axes to revert to the default font.更新 #3: Matplotlib 2.0.0 中有一个错误导致对数轴的刻度标签恢复为默认字体。 Should be fixed in 2.0.1 but I've included the workaround in the 2nd part of the answer.应该在 2.0.1 中修复,但我在答案的第二部分中包含了解决方法。

This answer is for anyone trying to change all the fonts, including for the legend, and for anyone trying to use different fonts and sizes for each thing.这个答案适用于任何试图更改所有字体的人,包括图例,以及任何试图为每件事使用不同字体和大小的人。 It does not use rc (which doesn't seem to work for me).它不使用 rc (这似乎对我不起作用)。 It is rather cumbersome but I could not get to grips with any other method personally.这相当麻烦,但我个人无法掌握任何其他方法。 It basically combines ryggyr's answer here with other answers on SO.它基本上将 ryggyr 的答案与 SO 上的其他答案结合在一起。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as font_manager

# Set the font dictionaries (for plot title and axis titles)
title_font = {'fontname':'Arial', 'size':'16', 'color':'black', 'weight':'normal',
              'verticalalignment':'bottom'} # Bottom vertical alignment for more space
axis_font = {'fontname':'Arial', 'size':'14'}

# Set the font properties (for use in legend)   
font_path = 'C:\Windows\Fonts\Arial.ttf'
font_prop = font_manager.FontProperties(fname=font_path, size=14)

ax = plt.subplot() # Defines ax variable by creating an empty plot

# Set the tick labels font
for label in (ax.get_xticklabels() + ax.get_yticklabels()):
    label.set_fontname('Arial')
    label.set_fontsize(13)

x = np.linspace(0, 10)
y = x + np.random.normal(x) # Just simulates some data

plt.plot(x, y, 'b+', label='Data points')
plt.xlabel("x axis", **axis_font)
plt.ylabel("y axis", **axis_font)
plt.title("Misc graph", **title_font)
plt.legend(loc='lower right', prop=font_prop, numpoints=1)
plt.text(0, 0, "Misc text", **title_font)
plt.show()

The benefit of this method is that, by having several font dictionaries, you can choose different fonts/sizes/weights/colours for the various titles, choose the font for the tick labels, and choose the font for the legend, all independently.这种方法的好处是,通过拥有多个字体字典,您可以为各种标题选择不同的字体/大小/粗细/颜色,为刻度标签选择字体,为图例选择字体,所有这些都是独立的。


UPDATE:更新:

I have worked out a slightly different, less cluttered approach that does away with font dictionaries, and allows any font on your system, even .otf fonts.我制定了一种稍微不同的、不那么杂乱的方法,它取消了字体字典,并允许系统上的任何字体,甚至是 .otf 字体。 To have separate fonts for each thing, just write more font_path and font_prop like variables.要为每个事物设置单独的字体,只需编写更多font_pathfont_prop的变量。

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.font_manager as font_manager
import matplotlib.ticker
# Workaround for Matplotlib 2.0.0 log axes bug https://github.com/matplotlib/matplotlib/issues/8017 :
matplotlib.ticker._mathdefault = lambda x: '\\mathdefault{%s}'%x 

# Set the font properties (can use more variables for more fonts)
font_path = 'C:\Windows\Fonts\AGaramondPro-Regular.otf'
font_prop = font_manager.FontProperties(fname=font_path, size=14)

ax = plt.subplot() # Defines ax variable by creating an empty plot

# Define the data to be plotted
x = np.linspace(0, 10)
y = x + np.random.normal(x)
plt.plot(x, y, 'b+', label='Data points')

for label in (ax.get_xticklabels() + ax.get_yticklabels()):
    label.set_fontproperties(font_prop)
    label.set_fontsize(13) # Size here overrides font_prop

plt.title("Exponentially decaying oscillations", fontproperties=font_prop,
          size=16, verticalalignment='bottom') # Size here overrides font_prop
plt.xlabel("Time", fontproperties=font_prop)
plt.ylabel("Amplitude", fontproperties=font_prop)
plt.text(0, 0, "Misc text", fontproperties=font_prop)

lgd = plt.legend(loc='lower right', prop=font_prop) # NB different 'prop' argument for legend
lgd.set_title("Legend", prop=font_prop)

plt.show()

Hopefully this is a comprehensive answer希望这是一个全面的答案

Here is a totally different approach that works surprisingly well to change the font sizes:这是一种完全不同的方法,可以很好地更改字体大小:

Change the figure size !改变图形大小

I usually use code like this:我通常使用这样的代码:

import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure(figsize=(4,3))
ax = fig.add_subplot(111)
x = np.linspace(0,6.28,21)
ax.plot(x, np.sin(x), '-^', label="1 Hz")
ax.set_title("Oscillator Output")
ax.set_xlabel("Time (s)")
ax.set_ylabel("Output (V)")
ax.grid(True)
ax.legend(loc=1)
fig.savefig('Basic.png', dpi=300)

The smaller you make the figure size, the larger the font is relative to the plot .使图形尺寸越小相对于绘图的字体就越大 This also upscales the markers.这也放大了标记。 Note I also set the dpi or dot per inch.注意我还设置了dpi或每英寸点数。 I learned this from a posting the AMTA (American Modeling Teacher of America) forum.我是从 AMTA(美国美国模特老师)论坛的帖子中了解到这一点的。 Example from above code:上面代码中的示例: 在此处输入图像描述

You can use plt.rcParams["font.size"] for setting font_size in matplotlib and also you can use plt.rcParams["font.family"] for setting font_family in matplotlib .您可以使用plt.rcParams["font.size"]matplotlib中设置font_size ,也可以使用plt.rcParams["font.family"]matplotlib中设置font_family Try this example:试试这个例子:

import matplotlib.pyplot as plt
plt.style.use('seaborn-whitegrid')

label = [1,2,3,4,5,6,7,8]
x = [0.001906,0.000571308,0.0020305,0.0037422,0.0047095,0.000846667,0.000819,0.000907]
y = [0.2943301,0.047778308,0.048003167,0.1770876,0.532489833,0.024611333,0.157498667,0.0272095]


plt.ylabel('eigen centrality')
plt.xlabel('betweenness centrality')
plt.text(0.001906, 0.2943301, '1 ', ha='right', va='center')
plt.text(0.000571308, 0.047778308, '2 ', ha='right', va='center')
plt.text(0.0020305, 0.048003167, '3 ', ha='right', va='center')
plt.text(0.0037422, 0.1770876, '4 ', ha='right', va='center')
plt.text(0.0047095, 0.532489833, '5 ', ha='right', va='center')
plt.text(0.000846667, 0.024611333, '6 ', ha='right', va='center')
plt.text(0.000819, 0.157498667, '7 ', ha='right', va='center')
plt.text(0.000907, 0.0272095, '8 ', ha='right', va='center')
plt.rcParams["font.family"] = "Times New Roman"
plt.rcParams["font.size"] = "50"
plt.plot(x, y, 'o', color='blue')

请看输出:

使用plt.tick_params(labelsize=14)

Here is what I generally use in Jupyter Notebook:这是我通常在 Jupyter Notebook 中使用的内容:

# Jupyter Notebook settings

from IPython.core.display import display, HTML
display(HTML("<style>.container { width:95% !important; }</style>"))
%autosave 0
%matplotlib inline
%load_ext autoreload
%autoreload 2

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"


# Imports for data analysis
import pandas as pd
import matplotlib.pyplot as plt
pd.set_option('display.max_rows', 2500)
pd.set_option('display.max_columns', 500)
pd.set_option('display.max_colwidth', 2000)
pd.set_option('display.width', 2000)
pd.set_option('display.float_format', lambda x: '%.3f' % x)

#size=25
size=15
params = {'legend.fontsize': 'large',
          'figure.figsize': (20,8),
          'axes.labelsize': size,
          'axes.titlesize': size,
          'xtick.labelsize': size*0.75,
          'ytick.labelsize': size*0.75,
          'axes.titlepad': 25}
plt.rcParams.update(params)

The changes to the rcParams are very granular, most of the time all you want is just scaling all of the font sizes so they can be seen better in your figure.rcParams的更改非常精细,大多数时候您只需要缩放所有字体大小,以便在您的图中可以更好地看到它们。 The figure size is a good trick but then you have to carry it for all of your figures.数字大小是一个很好的技巧,但是您必须为所有数字携带它。 Another way (not purely matplotlib, or maybe overkill if you don't use seaborn) is to just set the font scale with seaborn:另一种方法(不是纯粹的 matplotlib,或者如果你不使用 seaborn 可能会矫枉过正)是使用 seaborn 设置字体比例:

sns.set_context('paper', font_scale=1.4)

DISCLAIMER: I know, if you only use matplotlib then probably you don't want to install a whole module for just scaling your plots (I mean why not) or if you use seaborn, then you have more control over the options.免责声明:我知道,如果您只使用 matplotlib,那么您可能不想安装整个模块来缩放您的绘图(我的意思是为什么不这样做),或者如果您使用 seaborn,那么您可以更好地控制选项。 But there's the case where you have the seaborn in your data science virtual env but not using it in this notebook.但是在这种情况下,您的数据科学虚拟环境中有 seaborn,但在此笔记本中没有使用它。 Anyway, yet another solution.无论如何,还有另一个解决方案。

Based on the above stuff:基于以上内容:

import matplotlib.pyplot as plt
import matplotlib.font_manager as fm

fontPath = "/usr/share/fonts/abc.ttf"
font = fm.FontProperties(fname=fontPath, size=10)
font2 = fm.FontProperties(fname=fontPath, size=24)

fig = plt.figure(figsize=(32, 24))
fig.text(0.5, 0.93, "This is my Title", horizontalalignment='center', fontproperties=font2)

plot = fig.add_subplot(1, 1, 1)

plot.xaxis.get_label().set_fontproperties(font)
plot.yaxis.get_label().set_fontproperties(font)
plot.legend(loc='upper right', prop=font)

for label in (plot.get_xticklabels() + plot.get_yticklabels()):
    label.set_fontproperties(font)

I totally agree with Prof Huster that the simplest way to proceed is to change the size of the figure, which allows keeping the default fonts.我完全同意 Huster 教授的观点,最简单的方法是改变图形的大小,这样可以保持默认字体。 I just had to complement this with a bbox_inches option when saving the figure as a pdf because the axis labels were cut.在将图形保存为 pdf 时,我只需要使用 bbox_inches 选项来补充它,因为轴标签已被剪切。

import matplotlib.pyplot as plt
plt.figure(figsize=(4,3))
plt.savefig('Basic.pdf', bbox_inches='tight')

This is an extension to Marius Retegan answer .这是对 Marius Retegan答案的扩展。 You can make a separate JSON file with all your modifications and than load it with rcParams.update.您可以使用所有修改创建一个单独的 JSON 文件,然后使用 rcParams.update 加载它。 The changes will only apply to the current script.更改将仅适用于当前脚本。 So所以

import json
from matplotlib import pyplot as plt, rcParams

s = json.load(open("example_file.json")
rcParams.update(s)

and save this 'example_file.json' in the same folder.并将此“example_file.json”保存在同一文件夹中。

{
  "lines.linewidth": 2.0,
  "axes.edgecolor": "#bcbcbc",
  "patch.linewidth": 0.5,
  "legend.fancybox": true,
  "axes.color_cycle": [
    "#348ABD",
    "#A60628",
    "#7A68A6",
    "#467821",
    "#CF4457",
    "#188487",
    "#E24A33"
  ],
  "axes.facecolor": "#eeeeee",
  "axes.labelsize": "large",
  "axes.grid": true,
  "patch.edgecolor": "#eeeeee",
  "axes.titlesize": "x-large",
  "svg.fonttype": "path",
  "examples.directory": ""
}

I just wanted to point out that both the Herman Schaaf's and Pedro M Duarte's answers work but you have to do that before instantiating subplots() , these settings will not affect already instantiated objects.我只是想指出Herman SchaafPedro M Duarte 的答案都有效,但您必须在实例化subplots()之前这样做,这些设置不会影响已经实例化的对象。 I know it's not a brainer but I spent quite some time figuring out why are those answers not working for me when I was trying to use these changes after calling subplots().我知道这不是一个脑筋急转弯,但是当我在调用 subplots() 后尝试使用这些更改时,我花了很多时间弄清楚为什么这些答案对我不起作用。

For eg:例如:

import matplotlib.pyplot as plt
plt.rcParams.update({'font.size': 6,})
fig, ax = plt.subplots()
#create your plot
plt.show()

or或者

SMALL_SIZE = 8
MEDIUM_SIZE = 10
BIGGER_SIZE = 12

plt.rc('font', size=SMALL_SIZE)          # controls default text sizes
plt.rc('xtick', labelsize=SMALL_SIZE)    # fontsize of the tick labels
plt.rc('ytick', labelsize=SMALL_SIZE)    # fontsize of the tick labels
fig, ax = plt.subplots()
#create your plot
plt.show()

It is mentioned in a comment but deserves its own answer:评论中提到了它,但值得自己回答:

Modify both figsize= and dpi= in conjunction to adjust the figure size and the scale of all text labels:同时修改figsize=dpi=来调整图形大小和所有文本标签的比例:

fig, ax = plt.subplots(1, 1, figsize=(8, 4), dpi=100)

(or shorter:) (或更短:)

fig, ax = plt.subplots(figsize=(8, 4), dpi=100)

It's a bit tricky:这有点棘手:

  1. figsize actually controls the scale of the text relative to the plot extent (as well as the aspect ratio of the plot). figsize实际上控制文本对于绘图范围的比例(以及绘图的纵横比)。

  2. dpi adjusts the size of the figure within the notebook (keeping constant the relative scale of the text and the plot aspect ratio). dpi调整笔记本中图形的大小(保持文本的相对比例和绘图纵横比不变)。

I wrote a modified version of the answer by @ryggyr that allows for more control over the individual parameters and works on multiple subplots:我由@ryggyr 编写了答案的修改版本,它允许对单个参数进行更多控制并适用于多个子图:

def set_fontsizes(axes,size,title=np.nan,xlabel=np.nan,ylabel=np.nan,xticks=np.nan,yticks=np.nan):
    if type(axes) != 'numpy.ndarray':
        axes=np.array([axes])
    
    options = [title,xlabel,ylabel,xticks,yticks]
    for i in range(len(options)):
        if np.isnan(options[i]):
            options[i]=size
        
    title,xlabel,ylabel,xticks,yticks=options
    
    for ax in axes.flatten():
        ax.title.set_fontsize(title)
        ax.xaxis.label.set_size(xlabel)
        ax.yaxis.label.set_size(ylabel)
        ax.tick_params(axis='x', labelsize=xticks)
        ax.tick_params(axis='y', labelsize=yticks)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM