Nota
Haga clic aquí para descargar el código de ejemplo completo
Anotaciones #
Anotar texto con Matplotlib.
from matplotlib import pyplot as plt
Anotación básica #
Los usos del básico text()
colocarán el texto en una posición arbitraria en los Ejes. Un caso de uso común de texto es anotar alguna característica de la trama, y el
annotate()
método proporciona una funcionalidad de ayuda para facilitar las anotaciones. En una anotación, hay dos puntos a considerar: la ubicación que se anota representada por el argumento
xy y la ubicación del texto xytext . Ambos argumentos son tuplas.(x, y)
En este ejemplo, las ubicaciones xy (punta de flecha) y xytext (ubicación del texto) están en coordenadas de datos. Hay una variedad de otros sistemas de coordenadas que uno puede elegir: puede especificar el sistema de coordenadas de xy y xytext con una de las siguientes cadenas para xycoords y textcoords (el valor predeterminado es 'data')
argumento |
sistema coordinado |
---|---|
'puntos de figura' |
puntos de la esquina inferior izquierda de la figura |
'píxeles de figura' |
píxeles de la esquina inferior izquierda de la figura |
'fracción de figura' |
(0, 0) está en la parte inferior izquierda de la figura y (1, 1) está en la parte superior derecha |
'puntos de ejes' |
puntos de la esquina inferior izquierda de los ejes |
'píxeles de ejes' |
píxeles de la esquina inferior izquierda de los ejes |
'fracción de ejes' |
(0, 0) es la parte inferior izquierda de los ejes y (1, 1) es la parte superior derecha |
'datos' |
utilizar el sistema de coordenadas de datos de ejes |
Por ejemplo, para colocar las coordenadas del texto en coordenadas de ejes fraccionarios, se podría hacer:
ax.annotate('local max', xy=(3, 1), xycoords='data',
xytext=(0.8, 0.95), textcoords='axes fraction',
arrowprops=dict(facecolor='black', shrink=0.05),
horizontalalignment='right', verticalalignment='top',
)
Para los sistemas de coordenadas físicas (puntos o píxeles), el origen es la parte inferior izquierda de la figura o los ejes.
Opcionalmente, puede habilitar el dibujo de una flecha desde el texto hasta el punto anotado proporcionando un diccionario de propiedades de flecha en el argumento de palabra clave opcional arrowprops .
clave de puntas de flecha |
descripción |
---|---|
ancho |
el ancho de la flecha en puntos |
fractura |
la fracción de la longitud de la flecha ocupada por la cabeza |
ancho de cabeza |
el ancho de la base de la punta de la flecha en puntos |
encogerse |
mueva la punta y la base un porcentaje del punto anotado y el texto |
**kwargs |
cualquier clave para |
En el ejemplo a continuación, el punto xy está en coordenadas nativas ( el valor predeterminado de xycoords es 'data'). Para ejes polares, esto está en el espacio (theta, radio). El texto de este ejemplo está colocado en el sistema de coordenadas de figuras fraccionarias. matplotlib.text.Text
Los argumentos de palabras clave como horizontalalignment , verticalalignment y
fontsize se pasan annotate
a la
Text
instancia.
Para obtener más información sobre todas las cosas increíbles y maravillosas que puede hacer con las anotaciones, incluidas las flechas elegantes, consulte Anotaciones avanzadas y Anotación de gráficos .
¡No continúe a menos que ya haya leído la anotación básica
text()
y annotate()
!
Anotaciones avanzadas #
Anotar con texto con cuadro #
Comencemos con un ejemplo simple.
text
toma un argumento de palabra clave bbox , que dibuja un cuadro alrededor del texto:
t = ax.text(
0, 0, "Direction", ha="center", va="center", rotation=45, size=15,
bbox=dict(boxstyle="rarrow,pad=0.3", fc="cyan", ec="b", lw=2))
Se puede acceder al objeto de parche asociado con el texto mediante:
bb = t.get_bbox_patch()
El valor de retorno es un FancyBboxPatch
; Se puede acceder a las propiedades del parche (color de la cara, ancho del borde, etc.) y modificarlas como de costumbre.
FancyBboxPatch.set_boxstyle
establece la forma de la caja:
bb.set_boxstyle("rarrow", pad=0.6)
Los argumentos son el nombre del estilo de cuadro con sus atributos como argumentos de palabras clave. Actualmente, se implementan los siguientes estilos de caja.
Clase
Nombre
atributos
Circulo
circle
almohadilla = 0.3
Dflecha
darrow
almohadilla = 0.3
LAflecha
larrow
almohadilla = 0.3
RAflecha
rarrow
almohadilla = 0.3
Redondo
round
pad=0.3,rounding_size=Ninguno
ronda4
round4
pad=0.3,rounding_size=Ninguno
diente redondo
roundtooth
pad=0.3,tooth_size=Ninguno
Diente de sierra
sawtooth
pad=0.3,tooth_size=Ninguno
Cuadrado
square
almohadilla = 0.3
Tenga en cuenta que los argumentos de atributo se pueden especificar dentro del nombre del estilo con una coma de separación (esta forma se puede usar como valor de "estilo de caja" del argumento bbox al inicializar la instancia de texto)
bb.set_boxstyle("rarrow,pad=0.6")
Anotar con flecha #
annotate
dibuja una flecha que conecta dos puntos en un eje:
ax.annotate("Annotation",
xy=(x1, y1), xycoords='data',
xytext=(x2, y2), textcoords='offset points',
)
Esto anota un punto en xy en la coordenada dada ( xycoords ) con el texto en xytext dado en textcoords . A menudo, el punto anotado se especifica en la coordenada de datos y el texto de anotación en puntos desplazados . Consulte annotate
los sistemas de coordenadas disponibles.
Opcionalmente , se puede dibujar una flecha que conecta xy con xytext especificando el argumento arrowprops . Para dibujar solo una flecha, use una cadena vacía como primer argumento.
ax.annotate("",
xy=(0.2, 0.2), xycoords='data',
xytext=(0.8, 0.8), textcoords='data',
arrowprops=dict(arrowstyle="->",
connectionstyle="arc3"),
)
La flecha se dibuja de la siguiente manera:
Se crea una ruta que conecta los dos puntos, según lo especificado por el parámetro connectionstyle .
La ruta se recorta para evitar los parches patchA y patchB , si están configurados.
La ruta se reduce aún más con la reducción A y la reducción B (en píxeles).
La ruta se transmuta en un parche de flecha, según lo especificado por el parámetro arrowstyle .
La creación de la ruta de conexión entre dos puntos se controla mediante
connectionstyle
clave y están disponibles los siguientes estilos.
Nombre
atributos
angle
ánguloA=90,ánguloB=0,rad=0.0
angle3
ánguloA=90,ánguloB=0
arc
ánguloA=0,ánguloB=0,brazoA=Ninguno,brazoB=Ninguno,rad=0.0
arc3
rad=0.0
bar
brazoA=0.0,brazoB=0.0,fracción=0.3,ángulo=Ninguno
Tenga en cuenta que "3" en angle3
y arc3
pretende indicar que la ruta resultante es un segmento spline cuadrático (tres puntos de control). Como se discutirá a continuación, algunas opciones de estilo de flecha solo se pueden usar cuando la ruta de conexión es una spline cuadrática.
El comportamiento de cada estilo de conexión se demuestra (de forma limitada) en el siguiente ejemplo. (Advertencia: el comportamiento del bar
estilo actualmente no está bien definido, puede cambiar en el futuro).
La ruta de conexión (después de recortar y reducir) se muta a un parche de flecha, de acuerdo con el arrowstyle
.
Nombre
atributos
-
Ninguna
->
cabeza_longitud=0.4,cabeza_ancho=0.2
-[
anchoB=1.0,longitudB=0.2,ánguloB=Ninguno
|-|
anchoA=1.0,anchoB=1.0
-|>
cabeza_longitud=0.4,cabeza_ancho=0.2
<-
cabeza_longitud=0.4,cabeza_ancho=0.2
<->
cabeza_longitud=0.4,cabeza_ancho=0.2
<|-
cabeza_longitud=0.4,cabeza_ancho=0.2
<|-|>
cabeza_longitud=0.4,cabeza_ancho=0.2
fancy
head_length=0.4,head_width=0.4,tail_width=0.4
simple
head_length=0.5,head_width=0.5,tail_width=0.2
wedge
tail_width=0.3,shrink_factor=0.5
Algunos estilos de flecha solo funcionan con estilos de conexión que generan un segmento de spline cuadrático. Ellos son fancy
, simple
y wedge
. Para estos estilos de flecha, debe usar el estilo de conexión "angle3" o "arc3".
Si se proporciona la cadena de anotaciones, patchA se establece en el parche bbox del texto de forma predeterminada.
Al igual que con text
, se puede dibujar un cuadro alrededor del texto usando el argumento bbox
.
De forma predeterminada, el punto de inicio se establece en el centro de la extensión del texto. Esto se puede ajustar con relpos
el valor clave. Los valores se normalizan a la extensión del texto. Por ejemplo, (0, 0) significa esquina inferior izquierda y (1, 1) significa esquina superior derecha.
Colocación del artista en ubicaciones de ejes anclados #
Hay clases de artistas que se pueden colocar en un lugar anclado en los Ejes. Un ejemplo común es la leyenda. Este tipo de artista se puede crear usando la OffsetBox
clase. Algunas clases predefinidas están disponibles en matplotlib.offsetbox
y en
mpl_toolkits.axes_grid1.anchored_artists
.
from matplotlib.offsetbox import AnchoredText
fig, ax = plt.subplots()
at = AnchoredText(
"Figure 1a", prop=dict(size=15), frameon=True, loc='upper left')
at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
ax.add_artist(at)
<matplotlib.offsetbox.AnchoredText object at 0x7f2cdd7d9cf0>
La palabra clave loc tiene el mismo significado que en el comando leyenda.
Una aplicación simple es cuando el tamaño del artista (o colección de artistas) se conoce en tamaño de píxel durante el tiempo de creación. Por ejemplo, si desea dibujar un círculo con un tamaño fijo de 20 píxeles x 20 píxeles (radio = 10 píxeles), puede utilizar
AnchoredDrawingArea
. La instancia se crea con un tamaño del área de dibujo (en píxeles), y se pueden agregar artistas arbitrarios al área de dibujo. Tenga en cuenta que las extensiones de los artistas que se agregan al área de dibujo no están relacionadas con la ubicación del área de dibujo en sí. Solo importa el tamaño inicial.
Los artistas que se agregan al área de dibujo no deben tener un conjunto de transformación (se anulará) y las dimensiones de esos artistas se interpretan como una coordenada de píxel, es decir, el radio de los círculos en el ejemplo anterior son 10 píxeles y 5 píxeles. , respectivamente.
from matplotlib.patches import Circle
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredDrawingArea
fig, ax = plt.subplots()
ada = AnchoredDrawingArea(40, 20, 0, 0,
loc='upper right', pad=0., frameon=False)
p1 = Circle((10, 10), 10)
ada.drawing_area.add_artist(p1)
p2 = Circle((30, 10), 5, fc="r")
ada.drawing_area.add_artist(p2)
ax.add_artist(ada)
<mpl_toolkits.axes_grid1.anchored_artists.AnchoredDrawingArea object at 0x7f2cde0e07f0>
A veces, desea que sus artistas se escalen con la coordenada de datos (o coordenadas que no sean píxeles del lienzo). Puedes usar
AnchoredAuxTransformBox
la clase. Esto es similar a
AnchoredDrawingArea
excepto que la extensión del artista se determina durante el tiempo de dibujo respetando la transformación especificada.
La elipse del ejemplo siguiente tendrá un ancho y una altura correspondientes a 0,1 y 0,4 en las coordenadas de datos y se escalará automáticamente cuando cambien los límites de vista de los ejes.
from matplotlib.patches import Ellipse
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredAuxTransformBox
fig, ax = plt.subplots()
box = AnchoredAuxTransformBox(ax.transData, loc='upper left')
el = Ellipse((0, 0), width=0.1, height=0.4, angle=30) # in data coordinates!
box.drawing_area.add_artist(el)
ax.add_artist(box)
<mpl_toolkits.axes_grid1.anchored_artists.AnchoredAuxTransformBox object at 0x7f2cde48dea0>
Como en la leyenda, se puede establecer el argumento bbox_to_anchor. Usando HPacker y VPacker, puede tener un arreglo (?) de artista como en la leyenda (de hecho, así es como se crea la leyenda).
Tenga en cuenta que, a diferencia de la leyenda, bbox_transform
está configurado en IdentityTransform de forma predeterminada.
Sistemas de coordenadas para anotaciones #
Las anotaciones de Matplotlib admiten varios tipos de coordenadas. Algunos se describen en Anotación básica ; opciones más avanzadas son
una
Transform
instancia Por ejemplo,ax.annotate("Test", xy=(0.5, 0.5), xycoords=ax.transAxes)
es idéntico a
ax.annotate("Test", xy=(0.5, 0.5), xycoords="axes fraction")
Esto permite anotar un punto en otros ejes:
fig, (ax1, ax2) = plt.subplots(1, 2) ax2.annotate("Test", xy=(0.5, 0.5), xycoords=ax1.transData, xytext=(0.5, 0.5), textcoords=ax2.transData, arrowprops=dict(arrowstyle="->"))
una
Artist
instancia El valor xy (o xytext ) se interpreta como una coordenada fraccionaria del bbox (valor de retorno de get_window_extent ) del artista:an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data", va="center", ha="center", bbox=dict(boxstyle="round", fc="w")) an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1, # (1, 0.5) of the an1's bbox xytext=(30, 0), textcoords="offset points", va="center", ha="left", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->"))
Tenga en cuenta que debe asegurarse de que la extensión del artista coordenado ( an1 en el ejemplo anterior) esté determinada antes de que se dibuje an2 . Por lo general, esto significa que an2 debe dibujarse después de an1 .
Un objeto invocable que toma la instancia del renderizador como único argumento y devuelve un
Transform
o unBboxBase
. El valor devuelto luego se maneja como en (1), para transformaciones, o en (2), para bboxes. Por ejemplo,an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1, xytext=(30, 0), textcoords="offset points")
es idéntico a:
an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1.get_window_extent, xytext=(30, 0), textcoords="offset points")
Un par de especificaciones de coordenadas: la primera para la coordenada x y la segunda para la coordenada y; p.ej
annotate("Test", xy=(0.5, 1), xycoords=("data", "axes fraction"))
Aquí, 0.5 está en coordenadas de datos y 1 está en coordenadas de ejes normalizados. Cada una de las especificaciones de coordenadas también puede ser un artista o una transformación. Por ejemplo,
A veces, desea que su anotación tenga algunos "puntos de compensación", no desde el punto anotado sino desde algún otro punto.
text.OffsetFrom
es un ayudante para tales casos.Puede echar un vistazo a este ejemplo de Anotación de parcelas .
Usando ConnectionPatch #
ConnectionPatch
es como una anotación sin texto. Si bien annotate
es suficiente en la mayoría de las situaciones, ConnectionPatch
es útil cuando desea conectar puntos en diferentes ejes.
from matplotlib.patches import ConnectionPatch
xy = (0.2, 0.2)
con = ConnectionPatch(xyA=xy, coordsA=ax1.transData,
xyB=xy, coordsB=ax2.transData)
fig.add_artist(con)
El código anterior conecta el punto xy en las coordenadas de datos de ax1
con el punto xy en las coordenadas de datos de ax2
. Aquí hay un ejemplo simple.
Aquí, agregamos ConnectionPatch
a la figura (con add_artist
) en lugar de a cualquiera de los ejes: esto garantiza que se dibuje sobre ambos ejes y también es necesario si se usa constrained_layout para posicionar los ejes.
Temas avanzados #
Efecto de zoom entre ejes #
mpl_toolkits.axes_grid1.inset_locator
define algunas clases de parche útiles para interconectar dos ejes. Comprender el código requiere cierto conocimiento del sistema de transformación de Matplotlib.
Definir BoxStyle personalizado #
Puede utilizar un estilo de cuadro personalizado. El valor de boxstyle
puede ser un objeto invocable en las siguientes formas:
def __call__(self, x0, y0, width, height, mutation_size,
aspect_ratio=1.):
'''
Given the location and size of the box, return the path of
the box around it.
- *x0*, *y0*, *width*, *height* : location and size of the box
- *mutation_size* : a reference scale for the mutation.
- *aspect_ratio* : aspect-ratio for the mutation.
'''
path = ...
return path
Aquí hay un ejemplo completo.
De manera similar, puede definir un ConnectionStyle personalizado y un ArrowStyle personalizado. Vea el código fuente lib/matplotlib/patches.py
y verifique cómo se define cada clase de estilo.