Modifica il testo dell'etichetta di spunta


216

Voglio apportare alcune modifiche ad alcune etichette di spunta selezionate in una trama.

Ad esempio, se lo faccio:

label = axes.yaxis.get_major_ticks()[2].label
label.set_fontsize(size)
label.set_rotation('vertical')

la dimensione del carattere e l'orientamento dell'etichetta di spunta vengono modificati.

Tuttavia, se provi:

label.set_text('Foo')

l'etichetta di spunta non viene modificata. Anche se lo faccio:

print label.get_text()

nulla è stampato.

Ecco qualche altra stranezza. Quando ho provato questo:

 from pylab import *
 axes = figure().add_subplot(111)
 t = arange(0.0, 2.0, 0.01)
 s = sin(2*pi*t)
 axes.plot(t, s)
 for ticklabel in axes.get_xticklabels():
     print ticklabel.get_text()

Vengono stampate solo stringhe vuote, ma la trama contiene segni di spunta etichettati come '0.0', '0.5', '1.0', '1.5' e '2.0'.


Puoi fornire la trama che hai usato per ottenere l'etichetta?
Claudio,

Ricevi etichette vuote perché non hai ancora disegnato la tela. Se chiami draw()prima di provare a stampare le etichette, otterrai ciò che ti aspetti. L'impostazione delle singole etichette tick è purtroppo un tocco più difficile (ciò che sta accadendo è che il localizzatore tick e il formatter non sono stati ripristinati e sovrascrivono le cose quando si set_text). Aggiungerò un esempio tra poco, se qualcuno non mi batte. Devo prendere l'autobus, al momento, però.
Joe Kington,

@JoeKington: Fantastico! Non vedo l'ora di vedere la tua correzione.
repoman

@repoman - Beh, sembra che abbia parlato un po 'troppo presto. Quello che avevo in mente funziona per le versioni precedenti di matplotlib, ma non l'ultima versione. Devo fare un po 'più di scavo. Detto questo, non dovrebbe essere così complicato come lo è ...
Joe Kington,

Risposte:


298

Avvertenza: a meno che i ticklabel non siano già impostati su una stringa (come accade di solito in un boxplot), ciò non funzionerà con nessuna versione di matplotlib più recente di 1.1.0. Se stai lavorando con l'attuale master github, questo non funzionerà. Non sono ancora sicuro di quale sia il problema ... Potrebbe essere una modifica non intenzionale o potrebbe non essere ...

Normalmente, faresti qualcosa del genere:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()

# We need to draw the canvas, otherwise the labels won't be positioned and 
# won't have values yet.
fig.canvas.draw()

labels = [item.get_text() for item in ax.get_xticklabels()]
labels[1] = 'Testing'

ax.set_xticklabels(labels)

plt.show()

inserisci qui la descrizione dell'immagine

Per capire il motivo per cui devi saltare attraverso così tanti cerchi, devi capire un po 'di più su come è strutturato matplotlib.

Matplotlib evita deliberatamente il posizionamento "statico" delle zecche, ecc., A meno che non sia esplicitamente detto. Il presupposto è che vorrai interagire con la trama, quindi i limiti della trama, i segni di spunta, i segni di spunta, ecc. Cambieranno dinamicamente.

Pertanto, non puoi semplicemente impostare il testo di una determinata etichetta di spunta. Per impostazione predefinita, viene reimpostato dal localizzatore e dal formatter dell'asse ogni volta che viene disegnato il grafico.

Tuttavia, se i localizzatori e i formattatori sono impostati su statici ( FixedLocatore FixedFormatter, rispettivamente), le etichette dei tick rimangono invariate.

Questo è cosa set_*ticklabelso ax.*axis.set_ticklabelsfa.

Spero che ciò renda leggermente più chiaro il motivo per cui cambiare una singola etichetta tick è un po 'contorto.

Spesso, ciò che realmente vuoi fare è solo annotare una certa posizione. In tal caso, guarda annotateinvece.


10
questo non sembra funzionare con la versione corrente (1.20)!
Andrew Jaffe,

1
Se i ticklabel sono già impostati su una stringa come ad esempio in un diagramma a scatole, questo funziona ancora. Questo potrebbe essere ovvio, ma poiché la prima riga della risposta è che non funziona con le nuove versioni di matplotlib, gli utenti potrebbero ignorarlo completamente (inizialmente l'ho fatto). Magari menzionalo brevemente.
Joelostblom,

2
penso che puoi condensarlo fino a plt.gca (). set_xticklabels (etichette)
alexey

e se volessi che il carattere di "testing" fosse boldmentre altri usano il carattere di "light". C'è un modo per farlo?
Steven,

1
per coloro che usano questo in un quaderno jupyter può trarre vantaggio dal notare che fig.canvas.draw()è fondamentale
wander95

96

Si può anche fare questo con pylab e xticks

import matplotlib
import matplotlib.pyplot as plt
x = [0,1,2]
y = [90,40,65]
labels = ['high', 'low', 37337]
plt.plot(x,y, 'r')
plt.xticks(x, labels, rotation='vertical')
plt.show()

http://matplotlib.org/examples/ticks_and_spines/ticklabels_demo_rotation.html


Questa è una soluzione semplice e funziona con pyplot 1.5.1. Questo dovrebbe essere votato.
Wordsmith il

Sebbene la domanda non abbia posto questa domanda, apprezzo che questo esempio ti consenta di impostare la posizione dei segni di spunta contemporaneamente alla modifica delle loro etichette.
eclark

Dai moderni documenti matplotlib : "pylab è deprecato e il suo uso è fortemente scoraggiato a causa dell'inquinamento dello spazio dei nomi. Usa invece pyplot".
Nathaniel Jones,

93

Nelle versioni più recenti di matplotlib, se non si impostano le etichette tick con un sacco di strvalori, sono ''di default (e quando il grafico è disegnato le etichette sono semplicemente i valori tick). Sapendo questo, per ottenere l'output desiderato richiederebbe qualcosa del genere:

>>> from pylab import *
>>> axes = figure().add_subplot(111)
>>> a=axes.get_xticks().tolist()
>>> a[1]='change'
>>> axes.set_xticklabels(a)
[<matplotlib.text.Text object at 0x539aa50>, <matplotlib.text.Text object at 0x53a0c90>, 
<matplotlib.text.Text object at 0x53a73d0>, <matplotlib.text.Text object at 0x53a7a50>, 
<matplotlib.text.Text object at 0x53aa110>, <matplotlib.text.Text object at 0x53aa790>]
>>> plt.show()

e il risultato: inserisci qui la descrizione dell'immagine

e ora se controlli il _xticklabels, non sono più un gruppo di ''.

>>> [item.get_text() for item in axes.get_xticklabels()]
['0.0', 'change', '1.0', '1.5', '2.0']

Funziona nelle versioni dalla 1.1.1rc1versione corrente 2.0.


Grazie, questa è la risposta che stavo cercando. Soluzione più pulita IMO; basta fornire set_xticklabelsun elenco misto di stringhe e tick tick.
Luke Davis,

Tenere presente che se le etichette di spunta sono impostate come ints, le modifiche verranno modificate in float. Facilmente risolto ma vale la pena notare.
ApproachingDarknessFish

Questo ha funzionato ( ax.get_xticks().tolist()). La soluzione più votata no ( ax.get_xtickslabels()). In qualche modo non è stato in grado di estrarre le etichette prima che l' plt.show()eccedenza fosse eseguita, anche se l'ho usato fig.canvas.draw()come suggerito.
CypherX,

Cordiali saluti, dai moderni documenti matplotlib : "pylab è deprecato e il suo uso è fortemente scoraggiato a causa dell'inquinamento dello spazio dei nomi. Utilizzare invece pyplot".
Nathaniel Jones,

17

È passato un po 'di tempo da quando questa domanda è stata posta. Ad oggi ( matplotlib 2.2.2) e dopo alcune letture e prove, penso che il modo migliore / corretto sia il seguente:

Matplotlib dispone di un modulo di nome tickerche "contiene le classi di supporto completamente configurabili localizzazione segno di spunta e la formattazione" . Per modificare un segno di spunta specifico dalla trama, per me funziona quanto segue:

import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import numpy as np 

def update_ticks(x, pos):
    if x == 0:
        return 'Mean'
    elif pos == 6:
        return 'pos is 6'
    else:
        return x

data = np.random.normal(0, 1, 1000)
fig, ax = plt.subplots()
ax.hist(data, bins=25, edgecolor='black')
ax.xaxis.set_major_formatter(mticker.FuncFormatter(update_ticks))
plt.show()

Istogramma con valori casuali da una distribuzione normale

Avvertimento! xè il valore del segno di spunta ed posè la sua posizione relativa in ordine nell'asse. Si noti che posaccetta i valori a partire da 1, non 0come al solito durante l'indicizzazione.


Nel mio caso, stavo cercando di formattare l' y-axisistogramma con valori percentuali. mtickerha un'altra classe denominata PercentFormatterche può farlo facilmente senza la necessità di definire una funzione separata come prima:

import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
import numpy as np 

data = np.random.normal(0, 1, 1000)
fig, ax = plt.subplots()
weights = np.ones_like(data) / len(data)
ax.hist(data, bins=25, weights=weights, edgecolor='black')
ax.yaxis.set_major_formatter(mticker.PercentFormatter(xmax=1.0, decimals=1))
plt.show()

Istogramma con valori casuali da una distribuzione normale

In questo caso xmaxè il valore dei dati che corrisponde al 100%. Le percentuali vengono calcolate come x / xmax * 100, ecco perché ripariamo xmax=1.0. Inoltre, decimalsè il numero di posizioni decimali da posizionare dopo il punto.


12

La classe axes ha una funzione set_yticklabels che ti permette di impostare le etichette tick, in questo modo:

#ax is the axes instance
group_labels = ['control', 'cold treatment',
             'hot treatment', 'another treatment',
             'the last one']

ax.set_xticklabels(group_labels)

Sto ancora lavorando sul perché il tuo esempio sopra non ha funzionato.


3
Ma voglio solo cambiare una singola etichetta. Il trucco di cui sopra richiede di estrarre tutte le etichette dei tick e impostare quello desiderato su un nuovo valore. Ma come posso estrarre le etichette tick quando label.get_text () non restituisce nulla?
repoman

11

Questo funziona:

import matplotlib.pyplot as plt

fig, ax1 = plt.subplots(1,1)

x1 = [0,1,2,3]
squad = ['Fultz','Embiid','Dario','Simmons']

ax1.set_xticks(x1)
ax1.set_xticklabels(squad, minor=False, rotation=45)

FEDS


7

Questo funziona anche in matplotlib 3:

x1 = [0,1,2,3]
squad = ['Fultz','Embiid','Dario','Simmons']

plt.xticks(x1, squad, rotation=45)

5

Se non si lavora con fige axe si desidera modificare tutte le etichette (ad es. Per la normalizzazione), è possibile:

labels, locations = plt.yticks()
plt.yticks(labels, labels/max(labels))

1

Prova questo :

  fig,axis = plt.subplots(nrows=1,ncols=1,figsize=(13,6),sharex=True)
  axis.set_xticklabels(['0', 'testing', '10000', '20000', '30000'],fontsize=22)

-4

tu puoi fare:

for k in ax.get_xmajorticklabels():
    if some-condition:
        k.set_color(any_colour_you_like)

draw()

Qualcuno può spiegare perché questa risposta è così fortemente sottoposta a downgrade?
Hlynur Davíð Hlynsson,

@ HlynurDavíðHlynsson Penso che non abbia davvero a che fare con la domanda. Bene, forse con qualche modifica ... Per favore, modificala, se riesci a metterlo in relazione con la domanda. ;)
amato da Gesù, il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.