Como alterar o tamanho da fonte em um gráfico matplotlib

542

Como se altera o tamanho da fonte de todos os elementos (ticks, labels, title) em um gráfico matplotlib?

Eu sei como alterar os tamanhos dos rótulos dos marcadores, isso é feito com:

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

Mas como alguém muda o resto?

Herman Schaaf
fonte

Respostas:

629

Na documentação do matplotlib ,

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

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

Isso define a fonte de todos os itens para a fonte especificada pelo objeto kwargs, font ,.

Como alternativa, você também pode usar o rcParams updatemétodo sugerido nesta resposta :

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

ou

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

Você pode encontrar uma lista completa de propriedades disponíveis na página Customizing matplotlib .

Herman Schaaf
fonte
2
bom, exceto que substituir qualquer propriedade fontsize encontrado nele é maneira e_e
Yota
2
Onde posso encontrar mais opções para elementos como 'family', 'weight', etc.?
haccks
2
@HermanSchaaf; Eu visitei essa página antes. Eu gostaria de saber todas as opções para 'family'como 'normal', 'sans-serif', etc.
haccks
77
Uma vez que muitas pessoas começam com import matplotlib.pyplot as plt, você pôde gostar de salientar que pyplottem rctambém. Você pode fazer isso plt.rc(...sem precisar alterar suas importações.
LondonRob
21
Para o impaciente: O tamanho da fonte padrão é 10, como no segundo link.
FvD 16/10
304

Se você é um maníaco por controle como eu, convém definir explicitamente todos os tamanhos de fonte:

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

Observe que você também pode definir os tamanhos que chamam o rcmétodo matplotlib:

import matplotlib

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

# and so on ...
Pedro M Duarte
fonte
9
Eu tentei muitas das respostas. Este parece ser o melhor, pelo menos nos notebooks Jupyter. Basta copiar o bloco acima na parte superior e personalizar as três constantes de tamanho da fonte.
Feviktor 13/09/17
3
Concordo com fvitkor, essa é a melhor resposta!
SeF
9
Para mim, o tamanho do título não funcionou. Eu usei:plt.rc('axes', titlesize=BIGGER_SIZE)
Fernando Irarrázaval G
1
Eu acho que você pode combinar todas as configurações para o mesmo objeto em uma linha. Por exemplo,plt.rc('axes', titlesize=SMALL_SIZE, labelsize=MEDIUM_SIZE)
BallpointBen
198
matplotlib.rcParams.update({'font.size': 22})
Marius Retegan
fonte
1
Em alguns casos, essa solução funcionará apenas se eu criar um primeiro gráfico e, em seguida, "atualizar" conforme sugerido, o que leva ao tamanho da fonte atualizado para novas figuras. Talvez o primeiro lote seja necessário para inicializar o rcParams ...
Songio 7/03
191

Se você deseja alterar o tamanho da fonte para apenas um gráfico específico que já foi criado, tente o seguinte:

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)
ryggyr
fonte
1
Meu objetivo era ter a fonte de etiquetas xy, ticks e títulos de tamanhos diferentes. Uma versão modificada disso funcionou tão bem para mim.
EBE Isaac
6
Para obter as legendas também use ax.legend (). Get_texts (). Testado no Matplotlib 1.4.
James S.
Isso responde à pergunta mais diretamente. Obrigado.
jimh
Pode ser necessário ax=plt.gca()se o gráfico foi criado sem definir um eixo.
dylnan
@JamesS. Em vez disso ax.get_legend().get_texts(), use , porque ax.legend()redesenha toda a legenda com parâmetros padrão, além de retornar o valor de ax.get_legend().
Guimoute
69

Atualização: Veja a parte inferior da resposta para uma maneira um pouco melhor de fazê-lo.
Atualização # 2: Também descobri a alteração das fontes dos títulos das legendas.
Atualização # 3: Há um bug no Matplotlib 2.0.0 que está fazendo com que os rótulos de ticks dos eixos logarítmicos retornem à fonte padrão. Deve ser corrigido no 2.0.1, mas incluí a solução alternativa na 2ª parte da resposta.

Esta resposta é para qualquer um que tenta alterar todas as fontes, inclusive para a legenda, e para quem tenta usar fontes e tamanhos diferentes para cada coisa. Ele não usa rc (o que parece não funcionar para mim). É um tanto complicado, mas não pude entender pessoalmente nenhum outro método. Basicamente, combina a resposta de ryggyr aqui com outras respostas no 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()

A vantagem desse método é que, com vários dicionários de fontes, é possível escolher diferentes fontes / tamanhos / pesos / cores para os vários títulos, escolher a fonte para os rótulos dos marcadores e escolher a fonte para a legenda, tudo de forma independente.


ATUALIZAR:

Desenvolvi uma abordagem um pouco diferente e menos confusa que acaba com os dicionários de fontes e permite qualquer fonte em seu sistema, mesmo fontes .otf. Para ter fontes separadas para cada coisa, basta escrever mais font_pathe font_propgostar de variáveis.

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()

Espero que esta seja uma resposta abrangente

binaryfunt
fonte
40

Aqui está um totalmente diferente abordagem que funciona surpreendentemente bem para alterar o tamanho da fonte:

Alterar o tamanho da figura !

Eu costumo usar código como este:

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)

Quanto menor o tamanho da figura, maior a fonte é relativa à plotagem . Isso também aumenta os marcadores. Nota Também defino o dpiou ponto por polegada. Aprendi isso em uma postagem no fórum AMTA (American Modeling Teacher of America). Exemplo do código acima:insira a descrição da imagem aqui

Prof Huster
fonte
7
Para evitar o rótulo do eixo sendo cut-off, Salvar figura com o bbox_inchesargumento fig.savefig('Basic.png', bbox_inches="tight")
Paw
E se eu não estiver salvando a figura? Estou plotando no Juypter Notebook e os rótulos dos eixos resultantes são cortados.
Zythyr
Obrigado! Apontando as configurações de dpi foi extremamente útil para mim na preparação de versões para impressão de minhas parcelas sem ter que ajustar todos os tamanhos de linha, tamanhos de fonte, etc.
ybull
27

Usar plt.tick_params(labelsize=14)

Andrey Nikishaev
fonte
4
Obrigado pelo snippet de código, que pode fornecer ajuda imediata e limitada. Uma explicação adequada melhoraria bastante seu valor a longo prazo , descrevendo por que essa é uma boa solução para o problema e a tornaria mais útil para futuros leitores com outras perguntas semelhantes. Edite sua resposta para adicionar alguma explicação, incluindo as suposições que você fez.
31518 sepehr
22

Você pode usar plt.rcParams["font.size"]para definir font_sizeem matplotlibe também você pode usar plt.rcParams["font.family"]para definir font_familyem matplotlib. Tente este exemplo:

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')
hamed baziyad
fonte
10

Aqui está o que eu geralmente uso no 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)
stackoverflowuser2010
fonte
8

Com base no material acima:

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)
nvd
fonte
5

Esta é uma extensão da resposta de Marius Retegan . Você pode criar um arquivo JSON separado com todas as suas modificações e depois carregá-lo com rcParams.update. As alterações serão aplicadas apenas ao script atual. assim

import json
from matplotlib import pyplot as plt, rcParams

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

e salve este 'exemplo_arquivo.json' na mesma pasta.

{
  "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": ""
}
Michael H.
fonte
4

Eu concordo totalmente com o Prof Huster de que a maneira mais simples de proceder é alterar o tamanho da figura, o que permite manter as fontes padrão. Eu apenas tive que complementar isso com uma opção bbox_inches ao salvar a figura como um pdf, porque os rótulos dos eixos foram cortados.

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

fonte