2014-04-04 9 views
6

Vorrei posizionare una barra di colore all'interno di un grafico a dispersione specificando la posizione nelle coordinate di dati. Ecco un esempio di come funziona quando si specifica figura coordinateMatlotlib Python: posiziona la barra di colore nelle coordinate di dati

import numpy as np 
import matplotlib.pyplot as plt  

#Generate some random data: 
a = -2 
b = 2 
x = (b - a) * np.random.random(50) + a 
y = (b - a) * np.random.random(50) + a 
z = (b) * np.random.random(50) 

#Do a scatter plot 
fig = plt.figure() 
hdl = plt.scatter(x,y,s=20,c=z,marker='o',vmin=0,vmax=2) 
ax = plt.gca() 
ax.set_xlim([-2,2]) 
ax.set_ylim([-2,2]) 

#Specifying figure coordinates works fine: 
fig_coord = [0.2,0.8,0.25,0.05] 
cbar_ax = fig.add_axes(fig_coord) 

clevs = [0, 1 , 2] 
cb1 = plt.colorbar(hdl, cax=cbar_ax, orientation='horizontal', ticks=clevs) 

plt.show() 

... Ok, non si può includere un'immagine della trama qui perché mi manca la reputazione. Ma il codice sopra ti darà un'impressione ....

Ora la domanda è, come potrei posizionare la barra di colore alle coordinate di dati, per apparire ad esempio: a sinistra, in basso, larghezza, altezza: -1,5, 1,5 , 1, 0.25

Ho sperimentato alcune cose, come determinare la posizione degli assi all'interno della figura e trasformarla in coordinate di dati ma non ci sono riusciti.

Mille grazie per le idee o indicandomi già risposto a domande simili!

Ecco cosa ho fatto (non particolarmente bello ma aiuta). Grazie tcaswell!

#[lower left x, lower left y, upper right x, upper right y] of the desired colorbar: 
dat_coord = [-1.5,1.5,-0.5,1.75] 
#transform the two points from data coordinates to display coordinates: 
tr1 = ax.transData.transform([(dat_coord[0],dat_coord[1]),(dat_coord[2],dat_coord[3])]) 
#create an inverse transversion from display to figure coordinates: 
inv = fig.transFigure.inverted() 
tr2 = inv.transform(tr1) 
#left, bottom, width, height are obtained like this: 
datco = [tr2[0,0], tr2[0,1], tr2[1,0]-tr2[0,0],tr2[1,1]-tr2[0,1]] 
#and finally the new colorabar axes at the right position! 
cbar_ax = fig.add_axes(datco) 
#the rest stays the same: 
clevs = [0, 1 , 2] 
cb1 = plt.colorbar(hdl, cax=cbar_ax, orientation='horizontal', ticks=clevs) 

plt.show() 
+0

La barra di colore va nel proprio oggetto asse in modo da non specificare la posizione in unità di dati. È possibile risolvere le coordinate corrette della figura in un determinato punto nello spazio dati, ma non si aggiornerà se si esegue il pan/zoom. – tacaswell

+0

Vedi: http://matplotlib.org/1.3.1/users/transforms_tutorial.html Vuoi fare i dati -> schermo -> figura – tacaswell

+0

Grazie mille, il tuo commento ha aiutato a risolvere la mia domanda. – user3497890

risposta

1

Ecco cosa ho fatto, in base ai commenti alla mia domanda iniziale:

import numpy as np 
import matplotlib.pyplot as plt  

a = -2 
b = 2 

x = (b - a) * np.random.random(50) + a 
y = (b - a) * np.random.random(50) + a 
z = (b) * np.random.random(50) 

fig = plt.figure() 
hdl = plt.scatter(x,y,s=20,c=z,marker='o',vmin=0,vmax=2) 
ax = plt.gca() 
ax.set_xlim([-2,2]) 
ax.set_ylim([-2,2]) 

#[(lower left x, lower left y), (upper right x, upper right y)] of the desired colorbar: 
dat_coord = [(-1.5,1.5),(-0.5,1.75)] 
#transform the two points from data coordinates to display coordinates: 
tr1 = ax.transData.transform(dat_coord) 
#create an inverse transversion from display to figure coordinates: 
inv = fig.transFigure.inverted() 
tr2 = inv.transform(tr1) 
#left, bottom, width, height are obtained like this: 
datco = [tr2[0,0], tr2[0,1], tr2[1,0]-tr2[0,0],tr2[1,1]-tr2[0,1]] 
#and finally the new colorabar axes at the right position! 
cbar_ax = fig.add_axes(datco) 
#the rest stays the same: 
clevs = [0, 1 , 2] 
cb1 = plt.colorbar(hdl, cax=cbar_ax, orientation='horizontal', ticks=clevs) 

plt.show() 
1

Due graduale per specificare la posizione in coordinate dati di un assi:

  1. uso Axes.set_axes_locator() per impostare una funzione che restituisce un oggetto Bbox in figura coordinate.
  2. impostare la scatola fermaglio di tutti i bambini negli assi da set_clip_box() metodo:

Ecco il codice completo:

import numpy as np 
import matplotlib.pyplot as plt  

#Generate some random data: 
a = -2 
b = 2 
x = (b - a) * np.random.random(50) + a 
y = (b - a) * np.random.random(50) + a 
z = (b) * np.random.random(50) 

#Do a scatter plot 
fig = plt.figure() 
hdl = plt.scatter(x,y,s=20,c=z,marker='o',vmin=0,vmax=2) 
ax = plt.gca() 
ax.set_xlim([-2,2]) 
ax.set_ylim([-2,2]) 

#Specifying figure coordinates works fine: 
fig_coord = [0.2,0.8,0.25,0.05] 
cbar_ax = fig.add_axes(fig_coord) 

def get_ax_loc(cbar_ax, render): 
    from matplotlib.transforms import Bbox 
    tr = ax.transData + fig.transFigure.inverted() 
    bbox = Bbox(tr.transform([[1, -0.5], [1.8, 0]])) 
    return bbox 

clevs = [0, 1 , 2] 
cb1 = plt.colorbar(hdl, cax=cbar_ax, orientation='horizontal', ticks=clevs) 

def get_ax_loc(cbar_ax, render): 
    from matplotlib.transforms import Bbox 
    tr = ax.transData + fig.transFigure.inverted() 
    bbox = Bbox(tr.transform([[1, -0.5], [1.8, 0]])) 
    return bbox 

def set_children_clip_box(artist, box): 
    for c in artist.get_children(): 
     c.set_clip_box(box) 
     set_children_clip_box(c, box) 

cbar_ax.set_axes_locator(get_ax_loc) 
set_children_clip_box(cbar_ax, hdl.get_clip_box()) 

plt.show() 

Ed ecco l'output:

enter image description here

+0

Grazie per questa soluzione, sembra più robusto del mio. L'unico inconveniente è che non sono in grado di passare le coordinate dati alla funzione get_ax_loc. – user3497890

Problemi correlati