Matplotlib - gráficos 2D y 3D en Python

Versión original en inglés de J.R. Johansson ([email protected]) http://dml.riken.jp/~rob/

Traducido/Adaptado por G.F. Rubilar.

La última versión de estos notebooks de IPython está disponible en http://github.com/gfrubi/clases-python-cientifico.

La última versión del original (en inglés) de estos notebooks de IPython está disponible en http://github.com/jrjohansson/scientific-python-lectures.

Los otros notebooks de esta serie están listados en http://jrjohansson.github.com.

In [1]:
# Esta línea configura matplotlib para que muestre figuras en el cuaderno IPython, 
# en lugar de en una ventana nueva. Más detalles abajo. 
%matplotlib inline

Introducción

Matplotlib es una excelente librería gráfica 2D y 3D. Algunas de las muchas ventajas de esta librería son:

  • Es fácil comenzar a crear gráficos.
  • Incluye soporte para $\LaTeX$ en leyendas y textos.
  • Mucho control de cada elemento de la figura, incluyendo el tamaño y la densidad de puntos (DPI).
  • Formatos de salida de alta calidad, incluyendo PNG, PDF, SVG, EPS.
  • GUI para la exploración interactiva de figuras y soporte para la generación "headless" de archivos de figuras.

Una de las características claves de Matplotlib y que hace a Matplotlib altamente adecuado para generar figuras para publicaciones científicas es que todos los aspectos de la figura pueden ser controlados en programando. Esto es imporante para la reproducibilidad y conveniente cuando se necesita regenerar la figura con datos actualizados o cambios en su apariencia.

Más información en la página de Matplotlib: http://matplotlib.org/

API tipo MATLAB

Una forma sencilla para comenzar a graficar usando Matplotlib es usando la API tipo MATLAB que Matplotlib suministra, a través del módulo 'matplotlib.pyplot'.

Esta API está diseñada para que sea compatible con las funciones para graficar de MATLAB, de modo que resulta fácil para aquellos acostumbrados a usar MATLAB.

Importamos entonces el módulo pyplot:

In [2]:
from matplotlib.pyplot import *

Ejemplo

Una figura simple usando la API tipo MATLAB:

In [3]:
from numpy import *
x = linspace(0,5,50)
y = x**2
In [4]:
plot(x,y,'r')
xlabel('x')
ylabel('y')
title(u'Título') # el caracter `u` es necesario para incluir acentos en el texto
show() # muestra el gráfico en una ventana, si no se ha usado %matplotlib inline

La mayoría de las funciones gráficas de MATLAB están includas en el módulo pyplot. Por ejemplo, las funciones subplot y color/symbol:

In [5]:
subplot(1,2,1)
plot(x, y, 'r--')
subplot(1,2,2)
plot(y, x, 'g*-');

Lo positivo de la API tipo MATLAB Pyplot es que es fácil comenzar si ya se sabe usar MATLAB, y que requiere un mínimo de código para producir gráficos simples.

Sin embargo, esta API no es la más adecuada cuando se requiere producir gráficos complejos y/o se requiere controlar cada aspecto del gráfico. En este caso, es recomendable aprender y usar la API gráfica orientada al objeto de Matplotlib. Es muy poderosa y agradable de usar en caso de requerir figuras avanzadas, con sub-gráficos, objetos insertados y otros componentes.

La API orientada al objeto de Matplotlib

La idea principal de la programación orientada al objeto is que se tienen objetos sobre los cuales se pueden aplicar funciones y acciones, y que ningún estado de un objeto o programa debe ser global (tal como en la API tipo MATLAB). La ventaja de esta forma de trabajo se manifiesta cuando se requiere crear más de una figura, o cuando una figura contiene sub-figuras.

Para usar la API orientada al objeto comenzamos similarmente al ejemplo anterior, pero en lugar de crear una instancia de figura global almacenamos una referencia a la figura recién creada en la variable fig, y a partir de ella creamos nuevos ejes axes usando el método add_axes en la instancia fig de la clase Figure.

In [6]:
fig = figure()

ejes = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # izquierda, abajo, ancho, altura (rango 0 a 1)

ejes.plot(x,y,'r')

ejes.set_xlabel('x')
ejes.set_ylabel('y')
ejes.set_title(u'Título');

Aunque se requiere algo más de código, la ventaja es que ahora tenemos control completo sobre dónde se ubican los ejes, y además podemos agregar fácilmente más de un eje a la figura.

In [7]:
fig = figure()

axes1 = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # ejes principales
axes2 = fig.add_axes([0.2, 0.5, 0.4, 0.3]) # ejes del gráfico insertado

# figura principal
axes1.plot(x,y,'r')
axes1.set_xlabel('x')
axes1.set_ylabel('y')
axes1.set_title(u'Título principal')

# figura insertada
axes2.plot(y,x,'g')
axes2.set_xlabel('y')
axes2.set_ylabel('x')
axes2.set_title(u'Título secundario');

Si no nos importa ser explícitos sobre dónde estarán ubicados los ejes en el marco de nuestra figura, podemos usar uno de los muchos administradores de la distribución de los ejes que tiene Matplotlib. Un favorito es subplots, que puede ser usado de la forma siguiente:

In [8]:
fig, axes = subplots() # crea una nueva figura y un set de ejes

axes.plot(x,y,'r')
axes.set_xlabel('x')
axes.set_ylabel('y')
axes.set_title(u'Título');
In [9]:
 # crea una figura, con dos set de ejes, almacenados en el array axes
fig, axes = subplots(nrows=1, ncols=2)

for ax in axes:
    ax.plot(x, y, 'r')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_title(u'Título');

Fácil, pero no tan bonito debido a la superposición de los ejes y etiquetas en la parte central, cierto?

Podemos mejorar esto usando el método fig.tight_layout, que ajusta automáticamente la posición de los ejes en el marco de la figura de modo que no exista contenido que se superponga:

In [10]:
fig, axes = subplots(nrows=1, ncols=2)

for ax in axes:
    ax.plot(x, y, 'r')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_title(u'Título')
    
fig.tight_layout()

Tamaño de la figura, proporción de los ejes y DPI

Matplotlib permite especificar la proporción de los ejes, la densidad de puntos (DPI) y el tamaño de la figura cuando el objeto Figure es creado, usando los argumentos figsize y dpi. figsize es una tupla con el ancho y la altura de la figura en pulgadas, y dpi es el número de puntos (pixels) por pulgada. Para crear una figura de 800 por 400 pixels podemos usar:

In [11]:
fig = figure(figsize=(8,4), dpi=100)
<matplotlib.figure.Figure at 0x7fe8d7afc410>

Los mismos argumentos pueden ser usados en los administradores de distribución de ejes, como subplots.

In [12]:
fig, axes = subplots(figsize=(12,3))

axes.plot(x, y, 'r')
axes.set_xlabel('x')
axes.set_ylabel('y')
axes.set_title(u'Título');

Guardando figuras

Para guardar una figura en un archivo podemos usar el método savefig en la clase Figure.

In [13]:
fig.savefig("archivo.png")

Podemos, en forma opcional, especificar los DPI, además de elegir entre varios formatos.

In [14]:
fig.savefig("archivo.png", dpi=200)
In [15]:
fig.savefig("archivo.svg")

¿Qué formatos están disponibles y cuáles deberían ser usados para objener la mejor calidad?

Matplotlib puede crear gráficos de alta calidad en varios formatos, incluyendo PNG, JPG, EPS, SVG y PDF. Para publicaciones científicas, se recomienda usar PDF donde sea posible (y compilar documentos LaTeX con pdflatex, que puede incluir las figuras en PDF usando el comando includegraphics.

Leyendas, etiquetas y títulos

Ahora que hemos cubierto lo básico de cómo generar un marco de figura y agregar ejes al marco, veamos cómo decorar una figura con títulos, etiquetas de ejes y leyendas:

Títulos de figura

Se puede agregar un título a cada instancia de ejes de una figura. Para definir el título usamos el método set_title en la instancia de ejes:

In [16]:
ax.set_title(u"Título")
Out[16]:
<matplotlib.text.Text at 0x7fe8d7b293d0>

Etiquetas de ejes

Similarmente, usandos los métodos set_xlabel y set_ylabel podemos definir las etiquetas de los ejes X e Y:

In [17]:
ax.set_xlabel("x")
ax.set_ylabel("y")
Out[17]:
<matplotlib.text.Text at 0x7fe8d7b1e750>

Leyendas

Las leyendas de las curvas (o puntos, etc.) de una figura pueden ser agregados de dos maneras. Podemos usar el método legend de un eje y pasarle una lista/tupla de textos de lygendas para las curvas que ya han sido creadas previamente:

In [18]:
ax.legend(["curva1", "curva2", "curva3"]);

Este método sigue la API de MATLAB. Tiende a inducir a error y es poco flexible si se agregan o eliminan curvas de una figura (y como resultado se obtienen leyendas erroneamente asociadas a las curvas).

Es mejor usar los argumentos label="texto" cuando se agregan gráficos u otros objetos a la figura, y luego usar el método legend sin argumentos para agregar las leyendas:

In [19]:
ax.plot(x, x**2, label="curva1")
ax.plot(x, x**3, label="curva2")
ax.legend();

La ventaja de este método es que si se agregan o eliminan curvas a una figura, las leyendas se actualizan automáticamente.

La función legend acepta el argumento adicional loc que puede ser usado para especificar dónde se ubicará la leyenda en la figura. Los valores permitidos para loc son números que codifican los distintos lugares donde puede ser ubicada la leyenda. Ver http://matplotlib.org/users/legend_guide.html#legend-location para más detalles. Las alternativas más comunes son:

In [20]:
ax.legend(loc=0) # deja que Matplotlib decida la ubicación óptima
ax.legend(loc=1) # esquina superior derecha
ax.legend(loc=2) # esquina superior izquierda
ax.legend(loc=3) # esquina inferior izquierda
ax.legend(loc=4) # esquina inferior derecha
# .. muchas otras opciones disponiles
Out[20]:
<matplotlib.legend.Legend at 0x7fe8d7c2ac90>

La siguiente figura muestra cómo usar los títulos, etiquetas de ejes y leyendas descritas anteriormente:

In [21]:
fig, ax = subplots()

ax.plot(x, x**2, label="y = x**2")
ax.plot(x, x**3, label="y = x**3")
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title(u'Título')
ax.legend(loc=2); # esquina superior izquierda
Out[21]:
<matplotlib.legend.Legend at 0x7fe8d7503310>

Formateando texto: LaTeX, tamaño de letras, familia del tipo de letra

La figura anterior es funcional, pero (aún) no satisface los criterior para una figura usada en una publicación. Primero, necesitamos tener texto formateado en LaTeX, y además necesitamos poder ajustar el tamaño de las letras que aparecen en la publicación.

Matplotlib tiene un muy buen soporte de LaTeX. Lo único que se requiere hacer es usar el signo $ para encapsular cualquier texto (leyenda, título, etiqueta, etc.). Por ejemplo `"$y=x^3$"`.

Aquí, sin embargo, podemos encontrarnos con un sutil problema con el código LaTeX y las cadenas de texto de Python. En LaTeX frecuentemente usamos el backslash \ en los comandos, por ejemplo \alpha para producir el símbolo $\alpha$. Pero \ ya tiene un significado en las cadenas Python (el caracter de escape). Para evitar que Python malinterprete nuestro código LaTeX necesitamos usar cadenas de textos "crudas" ("raw"). Las cadenas de texto crudas son precedidas por 'r', por ejemplo r"\alpha" o r'\alpha' en lugar de "\alpha" y '\alpha'.

In [22]:
fig, ax = subplots()

ax.plot(x, x**2, label=r"$y = \alpha^2$")
ax.plot(x, x**3, label=r"$y = \alpha^3$")
ax.set_xlabel(r'$\alpha$', fontsize=18)
ax.set_ylabel(r'$y$', fontsize=18)
ax.set_title(u'Título')
ax.legend(loc=2); # esquina superior izquierda
Out[22]:
<matplotlib.legend.Legend at 0x7fe8d7448710>

Podemos también cambiar el tamaño y el tipo de letra globalmente, de modo que se aplique a todos los textos de una figura (etiquedas numéricas, etiquetas de ejes, títulos, leyendas, etc.):

In [23]:
# Actualiza los parámetros de configuración de Matplotlib:
matplotlib.rcParams.update({'font.size': 18, 'font.family': 'serif'})
In [24]:
fig, ax = subplots()

ax.plot(x, x**2, label=r"$y = \alpha^2$")
ax.plot(x, x**3, label=r"$y = \alpha^3$")
ax.set_xlabel(r'$\alpha$')
ax.set_ylabel(r'$y$')
ax.set_title(u'Título')
ax.legend(loc=2); # esquina superior izquierda
Out[24]:
<matplotlib.legend.Legend at 0x7fe8d73bff10>
In [25]:
# vuelve a la configuración original
matplotlib.rcParams.update({'font.size': 12, 'font.family': 'sans'})

Definiendo colores, anchos y tipos de línea

Colores

En Matplotlib podemos definir los colores de las líneas y otrs elementos gráficos de distintas maneras. Primero, podemos usar la sintaxis tipo MATLAB donde 'b' signifuca azul (blue) 'g' significa verde (green), etc. La API MATLAB para para seleccionar tipos de línea también está disponible: por ejemplo 'b.-' significa línas con puntso azules.

In [26]:
# Selección de color y estilo de línea tipo MATLAB
ax.plot(x, x**2, 'b.-') # línea con puntos azul
ax.plot(x, x**3, 'g--') # línea a trazos verde
Out[26]:
[<matplotlib.lines.Line2D at 0x7fe8d7b4f7d0>]

En Matplotlib también podemos definir colores por su nombre o sus códigos RGB, y opcionalmente suministrar un valor alfa, usando los argumentos color y alpha :

In [27]:
fig, ax = subplots()

ax.plot(x, x+1, color="red", alpha=0.5) # rojo semi-transparente
ax.plot(x, x+2, color="#1155dd")        # código RGB para un color azulado
ax.plot(x, x+3, color="#15cc55")        # código RGB para un color verdoso
Out[27]:
[<matplotlib.lines.Line2D at 0x7fe8d715bf50>]

Estilos de línea y marcadores

Para cambiar el ancho de una línea podemos usar el argumento linewidth o lw, y el estilo de línea puede ser seleccioando usando los argumentos linestyle o ls:

In [28]:
fig, ax = subplots(figsize=(12,6))

ax.plot(x, x+1, color="blue", linewidth=0.25)
ax.plot(x, x+2, color="blue", linewidth=0.50)
ax.plot(x, x+3, color="blue", linewidth=1.00)
ax.plot(x, x+4, color="blue", linewidth=2.00)

# posibles opciones de linestype: ‘-‘, ‘–’, ‘-.’, ‘:’, ‘steps’
ax.plot(x, x+5, color="red", lw=2, linestyle='-')
ax.plot(x, x+6, color="red", lw=2, ls='-.')
ax.plot(x, x+7, color="red", lw=2, ls=':')

# línea a trazos personalizada
line, = ax.plot(x, x+8, color="black", lw=1.50)
line.set_dashes([5, 10, 15, 10]) # formato: longitud de línea, longitud de espacio, ...

# posibles símbolos de marcadores: '+', 'o', '*', 's', ',', '.', '1', '2', '3', '4', ...
ax.plot(x, x+ 9, color="green", lw=2, ls='*', marker='+')
ax.plot(x, x+10, color="green", lw=2, ls='*', marker='o')
ax.plot(x, x+11, color="green", lw=2, ls='*', marker='s')
ax.plot(x, x+12, color="green", lw=2, ls='*', marker='1')

# Tamaño y color del marcador
ax.plot(x, x+13, color="purple", lw=1, ls='-', marker='o', markersize=2)
ax.plot(x, x+14, color="purple", lw=1, ls='-', marker='o', markersize=4)
ax.plot(x, x+15, color="purple", lw=1, ls='-', marker='o', markersize=8, markerfacecolor="red")
ax.plot(x, x+16, color="purple", lw=1, ls='-', marker='s', markersize=8, 
        markerfacecolor="yellow", markeredgewidth=2, markeredgecolor="blue");

Controlando la apariencia de los ejes

La apariencia de los ejes es un aspecto importante de una figura que comúnmente se requiere modificar para confeccionar un gráfico con calidad de publicacións. Necesitamos ser capaces de controlar dónde están ubicados los ticks y las etiquetas, modificar el tamaño de letra y posiblemente las etiquetas usadas en los ejes. En esta sección veremos cómo controlar estas propiedades en una figura de matplotlib.

Rango de los ejes

Lo primero que quisieramos configurar es el rango de los ejes. Podemos hacer esto usando los métodos set_ylim y set_xlim en un objeto ejes, o axis('tight') para obtener automáticamente rangos de ejes "apretados".

In [29]:
fig, axes = subplots(1, 3, figsize=(12, 4))

axes[0].plot(x, x**2, x, x**3)
axes[0].set_title("rango de ejes por defecto")

axes[1].plot(x, x**2, x, x**3)
axes[1].axis('tight')
axes[1].set_title("ejes apretados")

axes[2].plot(x, x**2, x, x**3)
axes[2].set_ylim([0, 60])
axes[2].set_xlim([2, 5])
axes[2].set_title("rango de ejes personalizado");

Posicionamiento de ticks y etiquetas de ticks personalizadas

Podemos determinar explícitamente dónde queremos que aparezcan los ticks de los ejes usando set_xticks y set_yticks, donde ambos métodos toman una lista de valores que determinan dónde se localizarán los ticks sobre el eje. Podemos también usar las funciones set_xticklabels y set_yticklabels para ingresar una lista de etiquetas personalizadas para cada tick:

In [30]:
fig, ax = subplots(figsize=(10, 4))

ax.plot(x, x**2, x, x**3, lw=2)

ax.set_xticks([1, 2, 3, 4, 5])
ax.set_xticklabels([r'$\alpha$', r'$\beta$', r'$\gamma$', r'$\delta$', r'$\epsilon$'], fontsize=18)

yticks = [0, 50, 100, 150]
ax.set_yticks(yticks)
ax.set_yticklabels(["$%.1f$" % y for y in yticks], fontsize=18); # usa etiquetas con formato LaTeX
Out[30]:
[<matplotlib.text.Text at 0x7fe8d6fe7810>,
 <matplotlib.text.Text at 0x7fe8d7c7aa90>,
 <matplotlib.text.Text at 0x7fe8dc0bf290>,
 <matplotlib.text.Text at 0x7fe8d7c41e90>]

En Matplotlib existen muchos métodos más avanzados para controlar la ubicación de los ticks mayores y menores, como por ejemplo la ubicación automática de acuerdo a distintos criterios. Ver http://matplotlib.org/api/ticker_api.html para más detalles.

Mallas de ejes

Usando el método grid en un eje podemos activar y desactivar las líneas de malla (grid). También podemos personalizar la apariencia de las líneas de malla, usando los mismos argumentos que usamos previamente con la función plot.

In [31]:
fig, axes = subplots(1, 2, figsize=(10,3))

# apariencia por defecto de la malla
axes[0].plot(x, x**2, x, x**3, lw=2)
axes[0].grid(True)

# apariencia personalizada de la malla
axes[1].plot(x, x**2, x, x**3, lw=2)
axes[1].grid(color='b', alpha=0.5, linestyle='dashed', linewidth=0.5)

"Espinas" de los ejes

También podemos cambiar las propiedades de las líneas de los ejes (las "espinas", spines):

In [32]:
fig, ax = subplots(figsize=(6,2))

ax.spines['bottom'].set_color('blue')
ax.spines['top'].set_color('blue')

ax.spines['left'].set_color('red')
ax.spines['left'].set_linewidth(2)

# desactiva la espina del eje derecho
ax.spines['right'].set_color("none")
ax.yaxis.tick_left() # sólo ticks a la izquierda

Ejes gemelos

Algunas veces es útil tener ejes x o y duales en una figura, por ejemplo cuando se grafican juntas curvas con diferentes unidades. Matplotlib incorpora esta opción usando las funciones twinx y twiny:

In [33]:
fig, ax1 = subplots()

ax1.plot(x, x**2, lw=2, color="blue")
ax1.set_ylabel(u"área $(m^2)$", fontsize=18, color="blue")
for label in ax1.get_yticklabels():
    label.set_color("blue")
    
ax2 = ax1.twinx()
ax2.plot(x, x**3, lw=2, color="red")
ax2.set_ylabel(r"volumen $(m^3)$", fontsize=18, color="red")
for label in ax2.get_yticklabels():
    label.set_color("red")

Ejes donde x e y pasan por cero

In [34]:
fig, ax = subplots()

ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')

ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0)) # define posición de la espina de x en x=0

ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))   # define posición de la espina de y en y=0

xx = np.linspace(-0.75, 1., 100)
ax.plot(xx, xx**3);

Otros estilos de gráficos 2D

Además de la función plot, existen varias otras funciones para generar distintos tipos de gráficos. Ver la galería de Matplotlib para una lista completa de los tipos disponibles: http://matplotlib.org/gallery.html. Algunos de los más útiles se muestra a continuación:

In [35]:
n = array([0,1,2,3,4,5])
In [36]:
fig, axes = subplots(1, 4, figsize=(12,3))

axes[0].scatter(xx, xx + 0.25*random.randn(len(xx)))

axes[1].step(n, n**2, lw=2)

axes[2].bar(n, n**2, align="center", width=0.5, alpha=0.5)

axes[3].fill_between(x, x**2, x**3, color="green", alpha=0.5);
In [37]:
# Gráfico polar usando add_axes y proyección polar
fig = figure()
ax = fig.add_axes([0.0, 0.0, .6, .6], polar=True)
t = linspace(0, 2 * pi, 100)
ax.plot(t, t, color='blue', lw=3);

Notas de texto

Se pueden incluir notas de texto en figuras de Matplotlib usando la función text. Tal como los textos en las etiquetas, leyendas títulos, incluye soporte para texto en formato LaTeX:

In [38]:
fig, ax = subplots()

ax.plot(xx, xx**2, xx, xx**3)

ax.text(0.15, 0.2, r"$y=x^2$", fontsize=20, color="blue")
ax.text(0.65, 0.1, r"$y=x^3$", fontsize=20, color="green");

Figuras con múltiples subplots e Figures with multiple subplots and insets

Se pueden agregar ejes a un marce de figura de Matplotlib usando make_axes o bien un administrador de distribución de sub-figuras tal como subplots, subplot2grid o gridspec:

subplots

In [39]:
fig, ax = subplots(2, 3)
fig.tight_layout()

subplot2grid

In [40]:
fig = figure()
ax1 = subplot2grid((3,3), (0,0), colspan=3)
ax2 = subplot2grid((3,3), (1,0), colspan=2)
ax3 = subplot2grid((3,3), (1,2), rowspan=2)
ax4 = subplot2grid((3,3), (2,0))
ax5 = subplot2grid((3,3), (2,1))
fig.tight_layout()

gridspec

In [41]:
import matplotlib.gridspec as gridspec
In [42]:
fig = figure()

gs = gridspec.GridSpec(2, 3, height_ratios=[2,1], width_ratios=[1,2,1])
for g in gs:
    ax = fig.add_subplot(g)
    
fig.tight_layout()

add_axes

El agregar ejes manualmente con add_axes es útil para incluir figuras en el interior de otras:

In [43]:
fig, ax = subplots()

ax.plot(xx, xx**2, xx, xx**3)
fig.tight_layout()

# figura interna
inset_ax = fig.add_axes([0.2, 0.55, 0.35, 0.35]) # X, Y, ancho, alto

inset_ax.plot(xx, xx**2, xx, xx**3)
inset_ax.set_title('zoom cerca del origen')

# define el rango de los ejes
inset_ax.set_xlim(-.2, .2)
inset_ax.set_ylim(-.005, .01)

# define la posición de los tick de los ejes
inset_ax.set_yticks([0, 0.005, 0.01])
inset_ax.set_xticks([-0.1,0,.1]);

Mapas de colores y líneas de contorno

Los mapas de colores y las líneas de contorno son útles para graficar funciones de dos variables. En la mayoría de los casos usaremos un mapa de colores para codificar una dimensión de los datosa. Existen varios mapas de colores predefinidos, y además definir mapas de colores personalizados es relativamente directo. Para ver una lista de los mapas de colores predefinidos, ver: http://www.scipy.org/Cookbook/Matplotlib/Show_colormaps.

In [44]:
alpha = 0.7
phi_ext = 2 * pi * 0.5

def flux_qubit_potential(phi_m, phi_p):
    return 2 + alpha - 2 * cos(phi_p)*cos(phi_m) - alpha * cos(phi_ext - 2*phi_p)
In [45]:
phi_m = linspace(0, 2*pi, 100)
phi_p = linspace(0, 2*pi, 100)
X,Y = meshgrid(phi_p, phi_m)
Z = flux_qubit_potential(X, Y).T

pcolor

In [46]:
fig, ax = subplots()

p = ax.pcolor(X/(2*pi), Y/(2*pi), Z, cmap=cm.RdBu, vmin=abs(Z).min(), vmax=abs(Z).max())
cb = fig.colorbar(p)

imshow

In [47]:
fig, ax = subplots()

im = imshow(Z, cmap=cm.RdBu, vmin=abs(Z).min(), vmax=abs(Z).max(), extent=[0, 1, 0, 1])
im.set_interpolation('bilinear')

cb = fig.colorbar(im)

contour

In [48]:
fig, ax = subplots()

cnt = contour(Z, cmap=cm.RdBu, vmin=abs(Z).min(), vmax=abs(Z).max(), extent=[0, 1, 0, 1])

Figuras 3D

Para producir gráficos 3D con Matplotlib, primero debemos crear una instancia de ejes de la clase Axes3D. Ejes 3D pueden ser agregados al marco de una figura de Matplotlib de la misma forma que para ejes 2D axes. Sin embargo, una forma conveniente para crear una instancia de eje 3D es usar el argumento projection='3d'en las funciones add_axes o `add_subplot.

In [49]:
from mpl_toolkits.mplot3d.axes3d import Axes3D

Gráficos de superficies

In [50]:
fig = figure(figsize=(14,6))

# `ax` es una instancia de ejes 3D, ya que se usó el argumento projection='3d' en add_subplot
ax = fig.add_subplot(1, 2, 1, projection='3d')

p = ax.plot_surface(X, Y, Z, rstride=4, cstride=4, linewidth=0)

# Gráfico de superficie con gradación de color y barra de color
ax = fig.add_subplot(1, 2, 2, projection='3d')
p = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)
cb = fig.colorbar(p, shrink=0.5)

Gráficos de mallas (Wire-frame)

In [51]:
fig = figure(figsize=(8,6))

ax = fig.add_subplot(1, 1, 1, projection='3d')

p = ax.plot_wireframe(X, Y, Z, rstride=4, cstride=4)

Gráficos de contorno con proyecciones

In [52]:
fig = figure(figsize=(8,6))

ax = fig.add_subplot(1,1,1, projection='3d')

ax.plot_surface(X, Y, Z, rstride=4, cstride=4, alpha=0.25)
cset = ax.contour(X, Y, Z, zdir='z', offset=-pi, cmap=cm.coolwarm)
cset = ax.contour(X, Y, Z, zdir='x', offset=-pi, cmap=cm.coolwarm)
cset = ax.contour(X, Y, Z, zdir='y', offset=3*pi, cmap=cm.coolwarm)

ax.set_xlim3d(-pi, 2*pi);
ax.set_ylim3d(0, 3*pi);
ax.set_zlim3d(-pi, 2*pi);