Cómo cambiar el tamaño de fuente en un gráfico matplotlib

708

¿Cómo se cambia el tamaño de fuente para todos los elementos (marcas, etiquetas, título) en un gráfico de matplotlib?

Sé cómo cambiar los tamaños de las etiquetas de tick, esto se hace con:

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

Pero, ¿cómo se cambia el resto?

852

De la documentación de matplotlib ,

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

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

Este establece la fuente de todos los artículos a la fuente especificada por el objeto kwargs, font.

Alternativamente, también puede usar el rcParams updatemétodo sugerido en esta respuesta :

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

o

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

Puede encontrar una lista completa de propiedades disponibles en la página Personalizar matplotlib .

12
  • 5
    agradable, excepto que anula cualquier propiedad de tamaño de fuente que se encuentre en su camino è_é
    yota
    25 de septiembre de 2014 a las 11:56
  • 3
    ¿Dónde puedo encontrar más opciones para los elementos como 'family', 'weight', etc.?
    haccks
    11/06/2015 a las 9:26
  • 111
    Dado que muchas personas comienzan con import matplotlib.pyplot as plt, es posible que desee señalar que también lo pyplotha hecho rc. Puede hacerlo plt.rc(...sin tener que cambiar sus importaciones. 27/07/15 a las 15:55
  • 39
    Para los impacientes: el tamaño de fuente predeterminado es 10, como en el segundo enlace.
    FvD
    16 oct 2017 a las 8:19
  • 4
    @ user32882: no de forma permanente, no se guarda en el disco, pero supongo que cambiaría los gráficos posteriores generados en el mismo código a menos que el valor original se almacene y restaure, lo que no siempre es conveniente. Puede hacer algo como for label in (ax.get_xticklabels() + ax.get_yticklabels()): label.set_fontsize(22)afectar el tamaño del texto en una sola figura. 28/01/19 a las 19:03
458

Si eres un fanático del control como yo, es posible que desees establecer explícitamente todos los tamaños de fuente:

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

Tenga en cuenta que también puede establecer los tamaños llamando al rcmétodo en matplotlib:

import matplotlib

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

# and so on ...
4
  • 11
    Probé muchas de las respuestas. Este se ve mejor, al menos en los cuadernos de Jupyter. Simplemente copie el bloque anterior en la parte superior y personalice las tres constantes de tamaño de fuente.
    fviktor
    13 de septiembre de 2017 a las 18:48
  • 3
    De acuerdo con fvitkor, ¡esa es la mejor respuesta!
    SeF
    8 de ene. De 2018 a las 18:23
  • 13
    Para mí, el tamaño del título no funcionó. Solía:plt.rc('axes', titlesize=BIGGER_SIZE) 6 de mayo de 2018 a las 5:06
  • 2
    Creo que puedes combinar todas las configuraciones para el mismo objeto en una línea. P.ej,plt.rc('axes', titlesize=SMALL_SIZE, labelsize=MEDIUM_SIZE) 21/08/18 a las 5:17
225

Si desea cambiar el tamaño de fuente solo para un gráfico específico que ya se ha creado, intente esto:

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)
5
  • 1
    Mi propósito era que la fuente de las etiquetas xy, los ticks y los títulos fueran de diferentes tamaños. Una versión modificada de esto funcionó muy bien para mí. 13/02/2017 a las 5:27
  • 9
    Para obtener las leyendas también use ax.legend (). Get_texts (). Probado en Matplotlib 1.4. 11 de septiembre de 2017 a las 4:19
  • Esto responde a la pregunta de manera más directa. Gracias.
    jimh
    9/06/18 a las 21:49
  • Es posible que necesite un ax=plt.gca()si el gráfico se creó sin definir un eje.
    dylnan
    28/01/19 a las 18:46
  • 2
    @JamesS. Más bien utilícelo ax.get_legend().get_texts(), porque ax.legend()vuelve a dibujar toda la leyenda con los parámetros predeterminados además de devolver el valor de ax.get_legend(). 21/11/19 a las 10:57
214
matplotlib.rcParams.update({'font.size': 22})
1
  • 2
    En caso de que esta solución funcione sólo si creo un primer gráfico, luego "actualizo" como se sugiere, lo que conduce a un tamaño de fuente actualizado para nuevas figuras. Quizás el primer gráfico sea necesario para inicializar rcParams ...
    Songio
    7 mar.20 a las 21:36
79

Actualización: consulte la parte inferior de la respuesta para conocer una forma un poco mejor de hacerlo.
Actualización n. ° 2: también descubrí cambiar las fuentes de los títulos de las leyendas.
Actualización n. ° 3: hay un error en Matplotlib 2.0.0 que hace que las etiquetas de marca de los ejes logarítmicos vuelvan a la fuente predeterminada. Debería corregirse en 2.0.1 pero he incluido la solución en la segunda parte de la respuesta.

Esta respuesta es para cualquiera que intente cambiar todas las fuentes, incluida la leyenda, y para cualquiera que intente usar diferentes fuentes y tamaños para cada cosa. No usa rc (que no parece funcionar para mí). Es bastante engorroso, pero no pude familiarizarme con ningún otro método personalmente. Básicamente, combina la respuesta de ryggyr aquí con otras respuestas sobre 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()

El beneficio de este método es que, al tener varios diccionarios de fuentes, puede elegir diferentes fuentes / tamaños / pesos / colores para los distintos títulos, elegir la fuente para las etiquetas de marca y elegir la fuente para la leyenda, todo de forma independiente.


ACTUALIZAR:

He elaborado un enfoque ligeramente diferente y menos desordenado que elimina los diccionarios de fuentes y permite cualquier fuente en su sistema, incluso fuentes .otf. Para tener fuentes separadas para cada cosa, simplemente escriba más font_pathy font_propvariables similares.

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

Con suerte, esta es una respuesta completa.

50

Aquí hay un enfoque totalmente diferente que funciona sorprendentemente bien para cambiar los tamaños de fuente:

¡Cambia el tamaño de la figura !

Normalmente uso un 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)

Cuanto menor sea ​​el tamaño de la figura, mayor será la fuente en relación con el gráfico . Esto también mejora los marcadores. Tenga en cuenta que también configuro el dpio el punto por pulgada. Aprendí esto de una publicación en el foro AMTA (American Modeling Teacher of America). Ejemplo del código anterior:ingrese la descripción de la imagen aquí

5
  • 9
    Para evitar que se corte la etiqueta del eje, guarde la figura con el bbox_inchesargumento fig.savefig('Basic.png', bbox_inches="tight")
    Paw
    22/10/18 a las 11:05
  • ¿Qué pasa si NO estoy guardando la figura? Estoy trazando en Juypter Notebook y las etiquetas de eje resultantes se cortan.
    Zythyr
    4 oct 2019 a las 7:43
  • ¡Gracias! Señalar la configuración de dpi fue extremadamente útil para mí al preparar versiones imprimibles de mis gráficos sin tener que ajustar todos los tamaños de línea, tamaños de fuente, etc.
    ybull
    23/10/19 a las 18:56
  • Para evitar que la etiqueta se corte, también en el cuaderno, como pregunta @Zythyr, puede usar plt.tight_layout() 8 jul.20 a las 9:35
  • 1
    @Zythyr Puede usar el argumento dpi = XXX también en la llamada de plt.figure (): plt.figure(figsize=(4,3), dpi=300)para lograr el mismo resultado sin guardar
    dnalow
    24 jul.20 a las 17:27
43

Usar plt.tick_params(labelsize=14)

2
  • 5
    Gracias por el fragmento de código, que puede proporcionar ayuda inmediata y limitada. Una explicación adecuada mejoraría enormemente su valor a largo plazo al describir por qué es una buena solución al problema y lo haría más útil para futuros lectores con otras preguntas similares. Edite su respuesta para agregar alguna explicación, incluidas las suposiciones que hizo.
    sepehr
    31 oct 2018 a las 17:29
  • 2
    ¿No cambia esto simplemente el tamaño de la fuente de la marca?
    JiK
    16 jul.20 a las 20:14
42

Se puede utilizar plt.rcParams["font.size"]para el ajuste font_sizeen matplotliby también se puede utilizar plt.rcParams["font.family"]para establecer font_familyen matplotlib. Prueba este ejemplo:

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

Por favor, vea el resultado:

28

Esto es lo que generalmente uso en 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)
9

Basado en lo anterior:

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

Estoy totalmente de acuerdo con el profesor Huster en que la forma más sencilla de proceder es cambiar el tamaño de la figura, lo que permite mantener las fuentes predeterminadas. Solo tuve que complementar esto con una opción bbox_inches al guardar la figura como pdf porque se cortaron las etiquetas de los ejes.

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

Esta es una extensión de la respuesta de Marius Retegan . Puede crear un archivo JSON separado con todas sus modificaciones y luego cargarlo con rcParams.update. Los cambios solo se aplicarán al script actual. Entonces

import json
from matplotlib import pyplot as plt, rcParams

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

y guarde este 'example_file.json' en la misma carpeta.

{
  "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": ""
}
4

Los cambios rcParamsson muy granulares, la mayoría de las veces todo lo que desea es escalar todos los tamaños de fuente para que se vean mejor en su figura. El tamaño de la figura es un buen truco, pero luego debes llevarlo para todas tus figuras. Otra forma (no puramente matplotlib, o tal vez exagerada si no usa seaborn) es simplemente establecer la escala de fuente con seaborn:

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

DESCARGO DE RESPONSABILIDAD: Lo sé, si solo usa matplotlib, probablemente no desee instalar un módulo completo solo para escalar sus parcelas (quiero decir, por qué no) o si usa seaborn, entonces tiene más control sobre las opciones. Pero existe el caso en el que tiene el Seaborn en su entorno virtual de ciencia de datos, pero no lo usa en este portátil. De todos modos, otra solución más.