python - matrices - Cómo ampliar una parte de la imagen e insertarla en la misma parcela en matplotlib
graficar matrices en python (4)
Me gustaría ampliar una parte de los datos / imágenes y trazarlos dentro de la misma figura. Se ve algo así como esta figura.
¿Es posible insertar una porción de la imagen ampliada dentro de la misma gráfica? Creo que es posible dibujar otra figura con subtrama pero dibuja dos figuras diferentes. También leí para agregar un parche para insertar un rectángulo / círculo, pero no estoy seguro de si es útil insertar una parte de la imagen en la figura. Básicamente, cargo datos del archivo de texto y los trazo usando los simples comandos de gráficos que se muestran a continuación.
Encontré un ejemplo relacionado de la galería de imágenes matplotlib here pero no estoy seguro de cómo funciona. Su ayuda es muy apreciada.
from numpy import *
import os
import matplotlib.pyplot as plt
data = loadtxt(os.getcwd()+txtfl[0], skiprows=1)
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.semilogx(data[:,1],data[:,2])
plt.show()
Jugar con código ejecutable es una de las formas más rápidas de aprender Python.
Comencemos con el here .
Teniendo en cuenta los comentarios en el código, parece que el código está dividido en 4 estrofas principales. La primera estrofa genera algunos datos, la segunda estrofa genera la trama principal, la tercera y cuarta estrofas crean los ejes insertados.
Sabemos cómo generar datos y trazar la trama principal, así que centrémonos en la tercera estrofa:
a = axes([.65, .6, .2, .2], axisbg=''y'')
n, bins, patches = hist(s, 400, normed=1)
title(''Probability'')
setp(a, xticks=[], yticks=[])
Copie el código de ejemplo en un archivo nuevo, llamado, digamos, test.py
¿Qué pasa si cambiamos el .65
a .3
?
a = axes([.35, .6, .2, .2], axisbg=''y'')
Ejecute el script:
python test.py
Encontrará el recuadro de "Probabilidad" movido a la izquierda. Entonces, la función de los axes
controla la ubicación del recuadro. Si juegas un poco más con los números, descubrirás que (.35, .6) es la ubicación de la esquina inferior izquierda del recuadro, y (.2, .2) es el ancho y alto del recuadro. Los números van de 0 a 1 y (0,0) es el ubicado en la esquina inferior izquierda de la figura.
Bien, ahora estamos cocinando. En la siguiente línea tenemos:
n, bins, patches = hist(s, 400, normed=1)
Puede reconocer esto como el comando matplotlib para dibujar un histograma , pero si no, cambiar el número 400 a, digamos, 10, producirá una imagen con un histograma mucho más grueso, así que de nuevo al jugar con los números pronto descubrirá que esta línea tiene algo que ver con la imagen dentro del recuadro.
Deberá llamar a semilogx(data[3:8,1],data[3:8,2])
aquí.
El title(''Probability'')
línea title(''Probability'')
obviamente genera el texto sobre el recuadro.
Finalmente llegamos a setp(a, xticks=[], yticks=[])
. No hay números para jugar, entonces, ¿qué pasa si solo comentamos toda la línea colocando un #
al comienzo de la línea?
# setp(a, xticks=[], yticks=[])
Vuelve a ejecutar el script Oh! ahora hay muchas marcas y etiquetas de tic en los ejes insertados. Multa. Entonces ahora sabemos que setp(a, xticks=[], yticks=[])
elimina las marcas y etiquetas de los ejes a
.
Ahora, en teoría, tiene suficiente información para aplicar este código a su problema. Pero hay un obstáculo potencial más: el ejemplo matplotlib utiliza from pylab import *
mientras que usted usa import matplotlib.pyplot as plt
.
Las preguntas frecuentes de matplotlib dicen que import matplotlib.pyplot as plt
es la forma recomendada de usar matplotlib cuando se escriben scripts, mientras que from pylab import *
se usa en sesiones interactivas. Así que lo estás haciendo de la manera correcta (aunque yo recomendaría usar import numpy as np
lugar de from numpy import *
también).
Entonces, ¿cómo convertimos el ejemplo de matplotlib para ejecutar con import matplotlib.pyplot as plt
?
Hacer la conversión requiere cierta experiencia con matplotlib. Generalmente, solo agrega plt.
frente a nombres simples como axes
y setp
, pero a veces la función viene de numpy, y a veces la llamada debe provenir de un objeto de ejes, no del módulo plt
. Se necesita experiencia para saber de dónde vienen todas estas funciones. Buscar en Google los nombres de las funciones junto con "matplotlib" puede ayudar. Leer el código de ejemplo puede generar experiencia, pero no hay un atajo fácil.
Entonces, el código convertido se convierte
ax2 = plt.axes([.65, .6, .2, .2], axisbg=''y'')
ax2.semilogx(t[3:8],s[3:8])
plt.setp(ax2, xticks=[], yticks=[])
Y podrías usarlo en tu código así:
from numpy import *
import os
import matplotlib.pyplot as plt
data = loadtxt(os.getcwd()+txtfl[0], skiprows=1)
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.semilogx(data[:,1],data[:,2])
ax2 = plt.axes([.65, .6, .2, .2], axisbg=''y'')
ax2.semilogx(data[3:8,1],data[3:8,2])
plt.setp(ax2, xticks=[], yticks=[])
plt.show()
La forma más simple es combinar "zoomed_inset_axes" y "mark_inset", cuya descripción y ejemplos relacionados se pueden encontrar aquí: Descripción general del kit de herramientas AxesGrid
La mejor manera que conozco para hacer esto es usar mpl_toolkits.axes_grid1.inset_locator (parte de matplotlib).
Hay un gran ejemplo con el código fuente aquí: https://github.com/NelleV/jhepc/tree/master/2013/entry10
Los pasos básicos para acercar una parte de una figura con matplotlib
import numpy as np
from matplotlib import pyplot as plt
# Generate the main data
X = np.linspace(-6, 6, 1024)
Y = np.sinc(X)
# Generate data for the zoomed portion
X_detail = np.linspace(-3, 3, 1024)
Y_detail = np.sinc(X_detail)
# plot the main figure
plt.plot(X, Y, c = ''k'')
# location for the zoomed portion
sub_axes = plt.axes([.6, .6, .25, .25])
# plot the zoomed portion
sub_axes.plot(X_detail, Y_detail, c = ''k'')
# insert the zoomed figure
# plt.setp(sub_axes)
plt.show()