2015-02-19 12 views
14

Vorrei spostare le etichette delle zecche orizzontalmente lungo l'asse x, senza spostare le tacche corrispondenti.Come spostare l'etichetta di una spunta in matplotlib?

In particolare, quando si ruotano le etichette con plt.setp, i centri del testo delle etichette rimangono allineati ai segni di spunta. Vorrei spostare quelle etichette a destra, in modo che le estremità vicine delle etichette si allineano invece come suggerito sull'immagine sottostante.

enter image description here

Sono consapevole this post e this one, tuttavia le risposte sono kludges interessanti piuttosto che severe risposte alla domanda.

il mio codice:

import matplotlib.pyplot as plt 
import numpy as np 
import datetime 

# my fake data 
dates = np.array([datetime.datetime(2000,1,1) + datetime.timedelta(days=i) for i in range(365*5)]) 
data = np.sin(np.arange(365*5)/365.0*2*np.pi - 0.25*np.pi) + np.random.rand(365*5) /3 

# creates fig with 2 subplots 
fig = plt.figure(figsize=(10.0, 6.0)) 
ax = plt.subplot2grid((2,1), (0, 0)) 
ax2 = plt.subplot2grid((2,1), (1, 0)) 
## plot dates 
ax2.plot_date(dates, data) 

# rotates labels 
plt.setp(ax2.xaxis.get_majorticklabels(), rotation=-45) 

# try to shift labels to the right 
ax2.xaxis.get_majorticklabels()[2].set_y(-.1) 
ax2.xaxis.get_majorticklabels()[2].set_x(10**99) 

plt.show() 

Stranamente, set_y si comporta come previsto, ma anche se ho impostato x ad un fantasillion, le etichette non sarebbe spostare di una virgola. (L'uso di plot_date possono introdurre ulteriori confusione, ma lo stesso effettivamente accade con plot.)

+0

io non sono in grado di replicare la tua immagine con il codice sopra ... – MattDMo

+0

@MattDMo Ho provato a copiarlo come tale ed eseguirlo, e ottengo la trama corretta. Ha due sottotrame però. Hai qualcosa? –

risposta

9

Ho trovato un modo per spostare le etichette di graduazione dell'asse x di una quantità arbitraria ed esatta, ma in questo modo corre pericolosamente vicino alle scogliere ripide e sdrucciolevoli che svettano sul mare della follia. Quindi, solo i più coraggiosi o disperati dovrebbero leggere ...

Detto questo, il problema è che la posizione x delle etichette è impostata quando il disegno è reso (non ho esaminato quella parte del codice, ma questa è la mia comprensione). Quindi tutto ciò che fai con set_x() viene sovrascritto più tardi. Tuttavia, c'è un modo per aggirare che: si può patch di scimmia set_x per alcune zecche in modo che le etichette non sono attratti in cui il renderer vuole disegnarli:

import types 
SHIFT = 10. # Data coordinates 
for label in ax2.xaxis.get_majorticklabels(): 
    label.customShiftValue = SHIFT 
    label.set_x = types.MethodType(lambda self, x: matplotlib.text.Text.set_x(self, x-self.customShiftValue), 
            label, matplotlib.text.Text) 

Si può fare questo in modo selettivo solo per le etichette che si desidera per cambiare e ovviamente è anche possibile utilizzare un turno diverso per ogni etichetta.

Se qualcuno sa come fare questo a un livello inferiore follia, sarei molto interessato ...

+0

Se si conoscono le posizioni di zecche, si può fare qualcosa di simile per pos, tick a zip (zecche, ax.xaxis.get_majorticklabels()): tick.set_x (pos - 0,1) = tick.set_x lambda x : Nessuno ... Non so come ottenere il codice in un commento, ma si spera che si ottiene il succo. – valhallasw

16

Invece di

ax2.xaxis.get_majorticklabels()[2].set_y(-.1) 
ax2.xaxis.get_majorticklabels()[2].set_x(10**99) 

utilizzare il set_horizontalalignment() per ogni tick sull'asse:

for tick in ax2.xaxis.get_majorticklabels(): 
    tick.set_horizontalalignment("left") 

risultante in:

+7

Grazie per la risposta. Tuttavia, non offre molta flessibilità: "sinistra", "destra", "centro". Sto cercando di assegnare le coordinate esatte. Ho passato così tanto tempo a provare, che la mia vera preoccupazione qui è piuttosto sapere se è del tutto possibile. –

3

Un altro modo di fare un allineamento orizzontale:

plt.xticks(ha='left') 
Problemi correlati