Nota
Haga clic aquí para descargar el código de ejemplo completo
Tutorial del artista #
Uso de objetos de artista para renderizar en el lienzo.
Hay tres capas en la API de Matplotlib.
el
matplotlib.backend_bases.FigureCanvases el área sobre la que se dibuja la figurael
matplotlib.backend_bases.Rendereres el objeto que sabe dibujar en elFigureCanvasy el
matplotlib.artist.Artistes el objeto que sabe cómo usar un renderizador para pintar sobre el lienzo.
FigureCanvasy
maneja todos los Rendererdetalles de hablar con juegos de herramientas de interfaz de usuario como wxPython o lenguajes de dibujo como PostScript®, y Artistmaneja todas las construcciones de alto nivel como representar y diseñar la figura, el texto y las líneas. El usuario típico pasará el 95% de su tiempo trabajando con Artists.
Hay dos tipos de Artists: primitivas y contenedores. Las primitivas representan los objetos gráficos estándar que queremos pintar en nuestro lienzo:
Line2D, Rectangle,
Text, AxesImage, etc., y los contenedores son lugares para colocarlos ( Axis,
Axesy Figure). El uso estándar es crear una Figureinstancia, usar el Figurepara crear una o más Axesinstancias
Subploty usar los Axesmétodos auxiliares de la instancia para crear las primitivas. En el siguiente ejemplo, creamos una
Figureinstancia usando matplotlib.pyplot.figure(), que es un método conveniente para instanciar Figureinstancias y conectarlas con su interfaz de usuario o kit de herramientas de dibujo.FigureCanvas. Como discutiremos a continuación, esto no es necesario: puede trabajar directamente con instancias de PostScript, PDF Gtk+ o wxPython FigureCanvas, crear una instancia Figures
directamente y conectarlas usted mismo, pero dado que nos estamos enfocando aquí en la
ArtistAPI, dejaremos pyplotmanejar algunos de esos detalles para nosotros:
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(2, 1, 1) # two rows, one column, first plot
Probablemente sea la Axesclase más importante en la API de Matplotlib y con la que trabajará la mayor parte del tiempo. Esto se debe a que Axeses el área de trazado en la que van la mayoría de los objetos, y Axestiene muchos métodos auxiliares especiales ( plot(),
text(),
hist(),
imshow()) para crear las primitivas gráficas más comunes ( Line2D,
Text,
Rectangle,
AxesImage, respectivamente). Estos métodos auxiliares tomarán sus datos (p. ej., numpymatrices y cadenas) y crearán Artistinstancias primitivas según sea necesario (p. ej. Line2D), las agregarán a los contenedores relevantes y las dibujarán cuando se solicite. La mayoría de ustedes probablemente esté familiarizado con el Subplot, que es solo un caso especial de un Axesque vive en una cuadrícula regular de filas por columnas deSubplotinstancias. Si desea crear un Axesen una ubicación arbitraria, simplemente use el
add_axes()método que toma una lista de valores en coordenadas de figuras relativas 0-1:[left, bottom, width, height]
fig2 = plt.figure()
ax2 = fig2.add_axes([0.15, 0.1, 0.7, 0.3])
Siguiendo con nuestro ejemplo:
En este ejemplo, axes la Axesinstancia creada por la
fig.add_subplotllamada anterior (recuerde Subplotque es solo una subclase de
Axes) y cuando llama ax.plot, crea una Line2Dinstancia y la agrega a Axes. En la siguiente sesión interactiva de IPython
, puede ver que la Axes.lineslista tiene una longitud de uno y contiene la misma línea que devolvió la llamada:line, = ax.plot...
In [101]: ax.lines[0]
Out[101]: <matplotlib.lines.Line2D at 0x19a95710>
In [102]: line
Out[102]: <matplotlib.lines.Line2D at 0x19a95710>
Si realiza llamadas posteriores a ax.plot(y el estado de espera está "activado", que es el valor predeterminado), se agregarán líneas adicionales a la lista. Puede eliminar una línea más tarde llamando a su removemétodo:
The Axes también tiene métodos de ayuda para configurar y decorar el eje x y el eje y, las etiquetas de marca y las etiquetas de los ejes:
xtext = ax.set_xlabel('my xdata') # returns a Text instance
ytext = ax.set_ylabel('my ydata')
Cuando llama ax.set_xlabel, pasa la información sobre la Text
instancia del XAxis. Cada Axes
instancia contiene una XAxisy una
YAxisinstancia, que manejan el diseño y el dibujo de las marcas, las etiquetas de marcas y las etiquetas de los ejes.
Intente crear la figura de abajo.
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
fig.subplots_adjust(top=0.8)
ax1 = fig.add_subplot(211)
ax1.set_ylabel('volts')
ax1.set_title('a sine wave')
t = np.arange(0.0, 1.0, 0.01)
s = np.sin(2*np.pi*t)
line, = ax1.plot(t, s, color='blue', lw=2)
# Fixing random state for reproducibility
np.random.seed(19680801)
ax2 = fig.add_axes([0.15, 0.1, 0.7, 0.3])
n, bins, patches = ax2.hist(np.random.randn(1000), 50,
facecolor='yellow', edgecolor='yellow')
ax2.set_xlabel('time (s)')
plt.show()

Personalizando tus objetos #
Cada elemento de la figura está representado por un Matplotlib
Artisty cada uno tiene una extensa lista de propiedades para configurar su apariencia. La figura en sí contiene
Rectangleexactamente el tamaño de la figura, que puede usar para establecer el color de fondo y la transparencia de las figuras. Del mismo modo, cada Axescuadro delimitador (el cuadro blanco estándar con bordes negros en el diagrama típico de Matplotlib) tiene una Rectangleinstancia que determina el color, la transparencia y otras propiedades de los ejes. Estas instancias se almacenan como variables miembro Figure.patchy Axes.patch("Patch" es un nombre heredado de MATLAB, y es un "parche" 2D de color en la figura, por ejemplo, rectángulos, círculos y polígonos). Cada Matplotlib Artisttiene las siguientes propiedades
Propiedad |
Descripción |
|---|---|
alfa |
La transparencia - un escalar de 0-1 |
animado |
Un booleano que se utiliza para facilitar el dibujo animado. |
hachas |
Los ejes en los que vive el artista, posiblemente ninguno |
clip_box |
El cuadro delimitador que recorta al Artista |
clip_en |
Si el recorte está habilitado |
clip_path |
El camino al que se recorta el artista |
contiene |
Una función de selección para probar si el artista contiene el punto de selección |
figura |
La instancia de la figura en la que vive el artista, posiblemente Ninguna. |
etiqueta |
Una etiqueta de texto (p. ej., para etiquetado automático) |
recogedor |
Un objeto de Python que controla la selección de objetos. |
transformar |
La transformación |
visible |
Un booleano si el artista debe ser dibujado |
orden Z |
Un número que determina el orden de dibujo |
rasterizado |
booleano; Convierte vectores en gráficos de trama (para compresión y transparencia EPS) |
Se accede a cada una de las propiedades con un setter o getter anticuado (sí, sabemos que esto irrita a los pitonistas y planeamos admitir el acceso directo a través de propiedades o rasgos, pero aún no se ha hecho). Por ejemplo, para multiplicar el alfa actual por la mitad:
a = o.get_alpha()
o.set_alpha(0.5*a)
Si desea establecer varias propiedades a la vez, también puede usar el setmétodo con argumentos de palabras clave. Por ejemplo:
o.set(alpha=0.5, zorder=2)
Si está trabajando de forma interactiva en el shell de python, una forma práctica de inspeccionar las Artistpropiedades es usar la
matplotlib.artist.getp()función (simplemente
getp()en pyplot), que enumera las propiedades y sus valores. Esto también funciona para las clases derivadas de Artist, por ejemplo, Figurey Rectangle. Aquí están las Figurepropiedades del rectángulo mencionadas anteriormente:
In [149]: matplotlib.artist.getp(fig.patch)
agg_filter = None
alpha = None
animated = False
antialiased or aa = False
bbox = Bbox(x0=0.0, y0=0.0, x1=1.0, y1=1.0)
capstyle = butt
children = []
clip_box = None
clip_on = True
clip_path = None
contains = None
data_transform = BboxTransformTo( TransformedBbox( Bbox...
edgecolor or ec = (1.0, 1.0, 1.0, 1.0)
extents = Bbox(x0=0.0, y0=0.0, x1=640.0, y1=480.0)
facecolor or fc = (1.0, 1.0, 1.0, 1.0)
figure = Figure(640x480)
fill = True
gid = None
hatch = None
height = 1
in_layout = False
joinstyle = miter
label =
linestyle or ls = solid
linewidth or lw = 0.0
patch_transform = CompositeGenericTransform( BboxTransformTo( ...
path = Path(array([[0., 0.], [1., 0.], [1.,...
path_effects = []
picker = None
rasterized = None
sketch_params = None
snap = None
transform = CompositeGenericTransform( CompositeGenericTra...
transformed_clip_path_and_affine = (None, None)
url = None
verts = [[ 0. 0.] [640. 0.] [640. 480.] [ 0. 480....
visible = True
width = 1
window_extent = Bbox(x0=0.0, y0=0.0, x1=640.0, y1=480.0)
x = 0
xy = (0, 0)
y = 0
zorder = 1
Las cadenas de documentación para todas las clases también contienen las Artist
propiedades, por lo que puede consultar la "ayuda" interactiva o
matplotlib.artist para obtener una lista de propiedades para un objeto determinado.
Contenedores de objetos #
Ahora que sabemos cómo inspeccionar y establecer las propiedades de un objeto dado que queremos configurar, necesitamos saber cómo llegar a ese objeto. Como se mencionó en la introducción, hay dos tipos de objetos: primitivos y contenedores. Las primitivas suelen ser las cosas que desea configurar (la fuente de una Text
instancia, el ancho de un Line2D), aunque los contenedores también tienen algunas propiedades; por ejemplo,
es un contenedor que contiene muchas de las primitivas en su trama, pero también tiene propiedades como para controlar si el eje x es 'lineal' o 'log'. En esta sección, revisaremos dónde almacenan los diversos objetos contenedores lo que desea obtener.Axes ArtistxscaleArtists
Figura contenedor #
El contenedor de nivel superior Artistes el
matplotlib.figure.Figurey contiene todo lo que se muestra en la figura. El fondo de la figura es un
Rectangleque se almacena en
Figure.patch. A medida que agrega subgráficos ( add_subplot()) y ejes ( add_axes()) a la figura, estos se agregarán al Figure.axes. Estos también son devueltos por los métodos que los crean:
In [156]: fig = plt.figure()
In [157]: ax1 = fig.add_subplot(211)
In [158]: ax2 = fig.add_axes([0.1, 0.1, 0.7, 0.3])
In [159]: ax1
Out[159]: <AxesSubplot:>
In [160]: print(fig.axes)
[<AxesSubplot:>, <matplotlib.axes._axes.Axes object at 0x7f0768702be0>]
Debido a que la figura mantiene el concepto de los "ejes actuales" (consulte
Figure.gcay
Figure.sca) para admitir la máquina de estado pylab/pyplot, no debe insertar ni eliminar ejes directamente de la lista de ejes, sino usar los
métodos add_subplot()y
add_axes()para insertar, y el
Axes.removemétodo borrar. Sin embargo, puede iterar sobre la lista de ejes o indexarla para obtener acceso a las Axesinstancias que desea personalizar. Aquí hay un ejemplo que enciende todas las cuadrículas de ejes:
for ax in fig.axes:
ax.grid(True)
La figura también tiene sus propios atributos images, y lines,
que puede usar para agregar primitivos directamente. Al hacerlo, el sistema de coordenadas predeterminado para el simplemente estará en píxeles (que generalmente no es lo que desea). Si, en cambio, utiliza métodos de nivel de figura para agregar artistas (p. ej., para agregar texto), el sistema de coordenadas predeterminado será "coordenadas de figura", donde (0, 0) es la parte inferior izquierda de la figura y (1, 1 ) es la parte superior derecha de la figura.patchestextFigureFigure.text
Al igual que con todos los Artists, puede controlar este sistema de coordenadas configurando la propiedad de transformación. Puede usar explícitamente "coordenadas de figura" configurando la Artisttransformación en fig.transFigure:
import matplotlib.lines as lines
fig = plt.figure()
l1 = lines.Line2D([0, 1], [0, 1], transform=fig.transFigure, figure=fig)
l2 = lines.Line2D([0, 1], [1, 0], transform=fig.transFigure, figure=fig)
fig.lines.extend([l1, l2])
plt.show()

Aquí hay un resumen de los artistas que contiene la figura.
Atributo de figura |
Descripción |
|---|---|
hachas |
Una lista de |
parche |
el |
imágenes |
Una lista de |
leyendas |
|
líneas |
Una lista de instancias de Figura |
parches |
Una lista de Figuras |
textos |
Una lista de |
Contenedor de ejes #
El matplotlib.axes.Axeses el centro del universo de Matplotlib: contiene la gran mayoría de todos los que se Artistsusan en una figura con muchos métodos de ayuda para crearlos y agregarlos
Artistsa sí mismo, así como métodos de ayuda para acceder y personalizar lo Artistsque contiene. Al igual que el
Figure, contiene a
que es a
para coordenadas cartesianas y a
para coordenadas polares; este parche determina la forma, el fondo y el borde de la región de trazado:Patch
patchRectangleCircle
ax = fig.add_subplot()
rect = ax.patch # a Rectangle instance
rect.set_facecolor('green')
Cuando llama a un método de trazado, por ejemplo, el canónico
ploty pasa matrices o listas de valores, el método creará una matplotlib.lines.Line2Dinstancia, actualizará la línea con todas las Line2Dpropiedades pasadas como argumentos de palabras clave, agregará la línea a Axesy se la devolverá. :
In [213]: x, y = np.random.rand(2, 100)
In [214]: line, = ax.plot(x, y, '-', color='blue', linewidth=2)
plotdevuelve una lista de líneas porque puede pasar múltiples pares x, y para trazar, y estamos desempaquetando el primer elemento de la lista de longitud uno en la variable de línea. La línea ha sido añadida a la
Axes.lineslista:
In [229]: print(ax.lines)
[<matplotlib.lines.Line2D at 0xd378b0c>]
De manera similar, los métodos que crean parches, como
bar()crear una lista de rectángulos, agregarán los parches a la Axes.patcheslista:
In [233]: n, bins, rectangles = ax.hist(np.random.randn(1000), 50)
In [234]: rectangles
Out[234]: <BarContainer object of 50 artists>
In [235]: print(len(ax.patches))
Out[235]: 50
No debe agregar objetos directamente a las
listas Axes.lineso , porque necesita hacer algunas cosas cuando crea y agrega un objeto:Axes.patchesAxes
Establece la propiedad
figureyaxesdelArtist;Establece la
Axestransformación predeterminada (a menos que ya se haya establecido una);Inspecciona los datos contenidos en el
Artistpara actualizar las estructuras de datos que controlan el escalado automático, de modo que los límites de vista se puedan ajustar para contener los datos trazados.
No obstante, puede crear objetos usted mismo y agregarlos directamente al
Axesuso de métodos auxiliares como add_liney
add_patch. Aquí hay una sesión interactiva comentada que ilustra lo que está pasando:
In [262]: fig, ax = plt.subplots()
# create a rectangle instance
In [263]: rect = matplotlib.patches.Rectangle((1, 1), width=5, height=12)
# by default the axes instance is None
In [264]: print(rect.axes)
None
# and the transformation instance is set to the "identity transform"
In [265]: print(rect.get_data_transform())
IdentityTransform()
# now we add the Rectangle to the Axes
In [266]: ax.add_patch(rect)
# and notice that the ax.add_patch method has set the axes
# instance
In [267]: print(rect.axes)
Axes(0.125,0.1;0.775x0.8)
# and the transformation has been set too
In [268]: print(rect.get_data_transform())
CompositeGenericTransform(
TransformWrapper(
BlendedAffine2D(
IdentityTransform(),
IdentityTransform())),
CompositeGenericTransform(
BboxTransformFrom(
TransformedBbox(
Bbox(x0=0.0, y0=0.0, x1=1.0, y1=1.0),
TransformWrapper(
BlendedAffine2D(
IdentityTransform(),
IdentityTransform())))),
BboxTransformTo(
TransformedBbox(
Bbox(x0=0.125, y0=0.10999999999999999, x1=0.9, y1=0.88),
BboxTransformTo(
TransformedBbox(
Bbox(x0=0.0, y0=0.0, x1=6.4, y1=4.8),
Affine2D(
[[100. 0. 0.]
[ 0. 100. 0.]
[ 0. 0. 1.]])))))))
# the default axes transformation is ax.transData
In [269]: print(ax.transData)
CompositeGenericTransform(
TransformWrapper(
BlendedAffine2D(
IdentityTransform(),
IdentityTransform())),
CompositeGenericTransform(
BboxTransformFrom(
TransformedBbox(
Bbox(x0=0.0, y0=0.0, x1=1.0, y1=1.0),
TransformWrapper(
BlendedAffine2D(
IdentityTransform(),
IdentityTransform())))),
BboxTransformTo(
TransformedBbox(
Bbox(x0=0.125, y0=0.10999999999999999, x1=0.9, y1=0.88),
BboxTransformTo(
TransformedBbox(
Bbox(x0=0.0, y0=0.0, x1=6.4, y1=4.8),
Affine2D(
[[100. 0. 0.]
[ 0. 100. 0.]
[ 0. 0. 1.]])))))))
# notice that the xlimits of the Axes have not been changed
In [270]: print(ax.get_xlim())
(0.0, 1.0)
# but the data limits have been updated to encompass the rectangle
In [271]: print(ax.dataLim.bounds)
(1.0, 1.0, 5.0, 12.0)
# we can manually invoke the auto-scaling machinery
In [272]: ax.autoscale_view()
# and now the xlim are updated to encompass the rectangle, plus margins
In [273]: print(ax.get_xlim())
(0.75, 6.25)
# we have to manually force a figure draw
In [274]: fig.canvas.draw()
Hay muchos, muchos Axesmétodos auxiliares para crear primitivos
Artistsy agregarlos a sus respectivos contenedores. La siguiente tabla resume una pequeña muestra de ellos, los tipos Artistque crean y dónde los almacenan.
Método auxiliar de ejes |
Artista |
Envase |
|---|---|---|
|
hacha.textos |
|
|
hacha.parches |
|
|
ax.lines y ax.patches |
|
|
hacha.parches |
|
|
hacha.parches |
|
|
hacha.images |
|
|
hacha.get_legend() |
|
|
ax.lines |
|
|
hacha.colecciones |
|
|
hacha.textos |
Además de todos estos Artists, el Axescontiene dos Artistcontenedores importantes: el XAxis
y YAxis, que manejan el dibujo de las marcas y etiquetas. Estos se almacenan como variables de instancia
xaxisy
yaxis. Los contenedores XAxisy YAxis
se detallarán a continuación, pero tenga en cuenta que Axescontiene muchos métodos de ayuda que reenvían las llamadas a las
Axisinstancias, por lo que a menudo no necesita trabajar con ellos directamente a menos que lo desee. Por ejemplo, puede establecer el color de fuente de las etiquetas de XAxisverificación utilizando el Axesmétodo auxiliar:
ax.tick_params(axis='x', labelcolor='orange')
A continuación se muestra un resumen de los artistas que Axescontiene el
Atributo de ejes |
Descripción |
|---|---|
artistas |
Una |
parche |
|
colecciones |
Una |
imágenes |
una |
líneas |
Una |
parches |
Una |
textos |
Una |
eje x |
una |
eje y |
una |
Se puede acceder a la leyenda mediante get_legend,
Contenedores de eje #
Las matplotlib.axis.Axisinstancias manejan el dibujo de las líneas de graduación, las líneas de cuadrícula, las etiquetas de graduación y la etiqueta del eje. Puede configurar las marcas izquierda y derecha por separado para el eje y, y las marcas superior e inferior por separado para el eje x. También almacena los datos y los intervalos de vista utilizados en el escalado automático, la panorámica y el zoom, así
Axis
como las instancias que controlan dónde se colocan las marcas y cómo se representan como cadenas.LocatorFormatter
Cada Axisobjeto contiene un labelatributo (esto es lo que se pyplotmodifica en las llamadas a xlabely
ylabel), así como una lista de marcas mayores y menores. Los ticks son
axis.XTicke axis.YTickinstancias, que contienen las primitivas de línea y texto reales que representan los ticks y las etiquetas de ticks. Debido a que las marcas se crean dinámicamente según sea necesario (p. ej., al desplazarse y hacer zoom), debe acceder a las listas de marcas principales y secundarias a través de sus métodos de acceso
axis.Axis.get_major_ticksy axis.Axis.get_minor_ticks. Aunque los ticks contienen todas las primitivas y se tratarán a continuación, las Axis
instancias tienen métodos de acceso que devuelven las líneas de ticks, las etiquetas de ticks, las ubicaciones de ticks, etc.:
fig, ax = plt.subplots()
axis = ax.xaxis
axis.get_ticklocs()

array([0. , 0.2, 0.4, 0.6, 0.8, 1. ])
[Text(0.0, 0, '0.0'), Text(0.2, 0, '0.2'), Text(0.4, 0, '0.4'), Text(0.6000000000000001, 0, '0.6'), Text(0.8, 0, '0.8'), Text(1.0, 0, '1.0')]
tenga en cuenta que hay el doble de líneas de verificación que etiquetas porque, de forma predeterminada, hay líneas de verificación en la parte superior e inferior, pero solo etiquetas de verificación debajo del eje x; sin embargo, esto se puede personalizar.
<a list of 12 Line2D ticklines objects>
Y con los métodos anteriores, solo obtiene listas de ticks principales de forma predeterminada, pero también puede solicitar los ticks menores:
axis.get_ticklabels(minor=True)
axis.get_ticklines(minor=True)
<a list of 0 Line2D ticklines objects>
Aquí hay un resumen de algunos de los métodos de acceso útiles del Axis
(estos tienen configuradores correspondientes cuando son útiles, como
set_major_formatter().)
Método de acceso del eje |
Descripción |
|---|---|
La escala del Eje, por ejemplo, 'log' o 'linear' |
|
La instancia de intervalo de los límites de la vista Axis |
|
La instancia de intervalo de los límites de datos de Axis |
|
Una lista de líneas de cuadrícula para el Eje |
|
La etiqueta Axis: una |
|
El texto de desplazamiento del eje: una |
|
Una lista de |
|
Una lista de |
|
Una lista de ubicaciones de Tick - palabra clave minor=Verdadero|Falso |
|
La |
|
La |
|
La |
|
La |
|
Una lista de |
|
Una lista de |
|
Encienda o apague la cuadrícula para los ticks mayores o menores |
Aquí hay un ejemplo, no recomendado por su belleza, que personaliza las propiedades de Axes y Tick.
# plt.figure creates a matplotlib.figure.Figure instance
fig = plt.figure()
rect = fig.patch # a rectangle instance
rect.set_facecolor('lightgoldenrodyellow')
ax1 = fig.add_axes([0.1, 0.3, 0.4, 0.4])
rect = ax1.patch
rect.set_facecolor('lightslategray')
for label in ax1.xaxis.get_ticklabels():
# label is a Text instance
label.set_color('red')
label.set_rotation(45)
label.set_fontsize(16)
for line in ax1.yaxis.get_ticklines():
# line is a Line2D instance
line.set_color('green')
line.set_markersize(25)
line.set_markeredgewidth(3)
plt.show()

Contenedores de garrapatas #
El matplotlib.axis.Tickes el objeto contenedor final en nuestro descenso del Figureal al
Axesal Axis
al al Tick. contiene las Tickinstancias de línea de cuadrícula y marca, así como las instancias de etiqueta para las marcas superior e inferior. Cada uno de estos es accesible directamente como un atributo de Tick.
Atributo de marca |
Descripción |
|---|---|
marca1línea |
una |
tick2line |
una |
cuadricula |
una |
etiqueta1 |
una |
etiqueta2 |
una |
Aquí hay un ejemplo que configura el formateador para las marcas del lado derecho con signos de dólar y los colorea de verde en el lado derecho del eje y.
import numpy as np
import matplotlib.pyplot as plt
# Fixing random state for reproducibility
np.random.seed(19680801)
fig, ax = plt.subplots()
ax.plot(100*np.random.rand(20))
# Use automatic StrMethodFormatter
ax.yaxis.set_major_formatter('${x:1.2f}')
ax.yaxis.set_tick_params(which='major', labelcolor='green',
labelleft=False, labelright=True)
plt.show()

Tiempo total de ejecución del script: (0 minutos 1.067 segundos)