2012-08-23 6 views
5

Ho alcuni riquadrati grafici in matplotlib che voglio ingrandire su un particolare intervallo y ([0,0.1]) usando inset axes. Non mi è chiaro dal example nella documentazione come dovrei farlo per più riquadrati nella stessa figura. Stavo cercando di modificare il codice fornito in questo esempio, ma c'era troppa complessità non necessaria. Il mio codice è piuttosto semplice:matplotlib: assi per inserti multipli per box multipli

# dataToPlot is a list of lists, containing some data. 
plt.figure() 
plt.boxplot(dataToPlot) 
plt.savefig('image.jpeg', bbox_inches=0) 

Come faccio ad aggiungere assi inserto e ingrandire il grafico a scatole prima dei due? Come posso farlo per entrambi?

EDIT: Ho provato il codice qui sotto, ma ecco quello che ho ottenuto: enter image description here

cosa è andato storto?

# what's the meaning of these two parameters? 
fig = plt.figure(1, [5,4]) 
# what does 111 mean? 
ax = fig.add_subplot(111) 
ax.boxplot(data) 
# ax.set_xlim(0,21) # done automatically based on the no. of samples, right? 
# ax.set_ylim(0,300) # done automatically based on max value in my samples, right? 
# Create the zoomed axes 
axins = zoomed_inset_axes(ax, 6, loc=1) # zoom = 6, location = 1 (upper right) 
axins.boxplot(data) 
# sub region of the original image 
#here I am selecting the first boxplot by choosing appropriate values for x1 and x2 
# on the y-axis, I'm selecting the range which I want to zoom in, right? 
x1, x2, y1, y2 = 0.9, 1.1, 0.0, 0.01 
axins.set_xlim(x1, x2) 
axins.set_ylim(y1, y2) 
# even though it's false, I still see all numbers on both axes, how do I remove them? 
plt.xticks(visible=False) 
plt.yticks(visible=False) 
# draw a bbox of the region of the inset axes in the parent axes and 
# connecting lines between the bbox and the inset axes area 
# what are fc and ec here? where do loc1 and loc2 come from? 
mark_inset(ax, axins, loc1=2, loc2=4, fc="none", ec="0.5") 
plt.savefig('img.jpeg', bbox_inches=0) 
+0

io non sono sicuro di sapere cosa si intende per "più grafici a scatole sulla stessa cifra". Avete più sottotrame? – samb8s

+0

No, 'dataToPlot' contiene più di un campione di dati e' plt.boxplot' lo tratta come tale: disegna tutti i grafici a scatole quanti sono i campioni nel suo input. –

+0

Quindi, non puoi semplicemente fare un altro 'axins = zoomed_inset_axes (ax, 6, loc = 2)' e impostare un intervallo di coordinate diverso per questo grafico successivo? – samb8s

risposta

14

Il loc determina la posizione dell'asse ingrandita, 1 per upper right, 2 per upper left e così via. Ho modificato leggermente il codice di esempio per generare più assi zoomati.

import matplotlib.pyplot as plt 

from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes 
from mpl_toolkits.axes_grid1.inset_locator import mark_inset 

import numpy as np 

def get_demo_image(): 
    from matplotlib.cbook import get_sample_data 
    import numpy as np 
    f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False) 
    z = np.load(f) 
    # z is a numpy array of 15x15 
    return z, (-3,4,-4,3) 


fig = plt.figure(1, [5,4]) 
ax = fig.add_subplot(111) 

# prepare the demo image 
Z, extent = get_demo_image() 
Z2 = np.zeros([150, 150], dtype="d") 
ny, nx = Z.shape 
Z2[30:30+ny, 30:30+nx] = Z 

# extent = [-3, 4, -4, 3] 
ax.imshow(Z2, extent=extent, interpolation="nearest", 
      origin="lower") 

axins = zoomed_inset_axes(ax, 6, loc=1) # zoom = 6 
axins.imshow(Z2, extent=extent, interpolation="nearest", 
      origin="lower") 

# sub region of the original image 
x1, x2, y1, y2 = -1.5, -0.9, -2.5, -1.9 
axins.set_xlim(x1, x2) 
axins.set_ylim(y1, y2) 

axins1 = zoomed_inset_axes(ax, 8, loc=2) # zoom = 6 
axins1.imshow(Z2, extent=extent, interpolation="nearest", 
      origin="lower") 

# sub region of the original image 
x1, x2, y1, y2 = -1.2, -0.9, -2.2, -1.9 
axins1.set_xlim(x1, x2) 
axins1.set_ylim(y1, y2) 

plt.xticks(visible=False) 
plt.yticks(visible=False) 

# draw a bbox of the region of the inset axes in the parent axes and 
# connecting lines between the bbox and the inset axes area 
mark_inset(ax, axins, loc1=2, loc2=4, fc="none", ec="0.5") 
mark_inset(ax, axins1, loc1=2, loc2=4, fc="none", ec="0.5") 

plt.draw() 
plt.show() 

enter image description here

Edit1:

Allo stesso modo, si può anche aggiungere asse ingrandita nel grafico a scatole. Ecco un esempio

from pylab import * 
from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes 
from mpl_toolkits.axes_grid1.inset_locator import mark_inset 

# fake up some data 
spread= rand(50) * 100 
center = ones(25) * 50 
flier_high = rand(10) * 100 + 100 
flier_low = rand(10) * -100 
data =concatenate((spread, center, flier_high, flier_low), 0) 

# fake up some more data 
spread= rand(50) * 100 
center = ones(25) * 40 
flier_high = rand(10) * 100 + 100 
flier_low = rand(10) * -100 
d2 = concatenate((spread, center, flier_high, flier_low), 0) 
data.shape = (-1, 1) 
d2.shape = (-1, 1) 
data = [data, d2, d2[::2,0]] 

# multiple box plots on one figure 
fig = plt.figure(1, [5,4]) 
ax = fig.add_subplot(111) 
ax.boxplot(data) 
ax.set_xlim(0.5,5) 
ax.set_ylim(0,300) 

# Create the zoomed axes 
axins = zoomed_inset_axes(ax, 3, loc=1) # zoom = 3, location = 1 (upper right) 
axins.boxplot(data) 

# sub region of the original image 
x1, x2, y1, y2 = 0.9, 1.1, 125, 175 
axins.set_xlim(x1, x2) 
axins.set_ylim(y1, y2) 
plt.xticks(visible=False) 
plt.yticks(visible=False) 

# draw a bbox of the region of the inset axes in the parent axes and 
# connecting lines between the bbox and the inset axes area 
mark_inset(ax, axins, loc1=2, loc2=4, fc="none", ec="0.5") 

show() 

enter image description here

Edit2

Nel caso la distribuzione è eterogeneo, cioè, la maggior parte dei valori sono piccole con pochi valori molto grandi, la procedura zoom sopra potrebbe non funzionare, in quanto ingrandirà sia l'asse x che l'asse . In tal caso è preferibile modificare la scala di y-axis in log.

from pylab import * 

# fake up some data 
spread= rand(50) * 1 
center = ones(25) * .5 
flier_high = rand(10) * 100 + 100 
flier_low = rand(10) * -100 
data =concatenate((spread, center, flier_high, flier_low), 0) 

# fake up some more data 
spread= rand(50) * 1 
center = ones(25) * .4 
flier_high = rand(10) * 100 + 100 
flier_low = rand(10) * -100 
d2 = concatenate((spread, center, flier_high, flier_low), 0) 
data.shape = (-1, 1) 
d2.shape = (-1, 1) 
data = [data, d2, d2[::2,0]] 

# multiple box plots on one figure 
fig = plt.figure(1, [5,4]) # Figure Size 
ax = fig.add_subplot(111) # Only 1 subplot 
ax.boxplot(data) 
ax.set_xlim(0.5,5) 
ax.set_ylim(.1,300) 
ax.set_yscale('log') 

show() 

enter image description here

+0

Grazie. La documentazione su questo è ancora troppo complessa per i miei scopi. Ho modificato il mio post originale per sottolineare quello che sto facendo in questo momento e rimosso tutte le righe inutili dall'esempio online. Potresti modificare il mio codice, quindi posso vedere cosa dovrei effettivamente fare? Grazie. –

+1

Controllare la risposta modificata. Se hai difficoltà a comprendere una parte specifica del codice, fammelo sapere. – imsc

+0

Grazie. Ho modificato il mio post e aggiunto l'output del tuo codice e le domande su alcuni dei parametri utilizzati. –