Je souhaite apporter quelques modifications à quelques étiquettes de tick sélectionnées dans un graphique.
Par exemple, si je le fais:
label = axes.yaxis.get_major_ticks()[2].label
label.set_fontsize(size)
label.set_rotation('vertical')
la taille de la police et l'orientation du libellé de la tique sont modifiées.
Cependant, si vous essayez:
label.set_text('Foo')
l'étiquette de la tique est pas modifiée. Aussi si je le fais:
print label.get_text()
rien n'est imprimé.
Voici un peu plus d'étrangeté. Quand j'ai essayé ceci:
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()
Seules des chaînes vides sont imprimées, mais le tracé contient des graduations intitulées «0.0», «0.5», «1.0», «1.5» et «2.0».
Avertissement: à moins que les étiquettes de contrôle ne soient déjà définies sur une chaîne (comme c'est généralement le cas dans une boîte à moustaches, par exemple), cela ne fonctionnera avec aucune version de matplotlib plus récente que 1.1.0
. Si vous travaillez avec le maître github actuel, cela ne fonctionnera pas. Je ne sais pas encore quel est le problème ... Ce peut être un changement inattendu, ou peut-être pas ...
Normalement, vous feriez quelque chose dans ce sens:
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()
Pour comprendre la raison pour laquelle vous devez franchir autant d'obstacles, vous devez comprendre un peu plus la structure de matplotlib.
Matplotlib évite délibérément de faire un positionnement "statique" des ticks, etc., sauf indication contraire explicite. L'hypothèse est que vous souhaiterez interagir avec l'intrigue, de sorte que les limites de l'intrigue, des ticks, des étiquettes de contrôle, etc. changeront de manière dynamique.
Par conséquent, vous ne pouvez pas simplement définir le texte d'une étiquette de tick. Par défaut, il est redéfini par le localisateur et le formateur de l'axe à chaque fois que le tracé est tracé.
Toutefois, si les localisateurs et les formats sont définis pour être statiques (FixedLocator
et FixedFormatter
, respectivement), les libellés de coches restent inchangés.
C'est ce que font set_*ticklabels
ou ax.*axis.set_ticklabels
.
Espérons que cela rend un peu plus clair la raison pour laquelle changer une étiquette de tick individuelle est un peu compliqué.
Souvent, ce que vous voulez réellement faire est simplement d'annoter une certaine position. Dans ce cas, examinez plutôt annotate
.
Dans les versions plus récentes de matplotlib
, si vous ne définissez pas les étiquettes de ticks avec un ensemble de valeurs str
, elles sont ''
par défaut (et lorsque le tracé est tracé, les étiquettes sont simplement les valeurs de ticks). Sachant cela, pour obtenir le résultat souhaité, il faudrait quelque chose comme ceci:
>>> 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()
et le résultat:
et maintenant, si vous vérifiez le _xticklabels
, ils ne sont plus un groupe de ''
.
>>> [item.get_text() for item in axes.get_xticklabels()]
['0.0', 'change', '1.0', '1.5', '2.0']
Cela fonctionne dans les versions de 1.1.1rc1
à la version actuelle 2.0
.
On peut aussi le faire avec pylab et xticks
import pylab 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
La classe d'axes a une fonction set_yticklabels qui vous permet de définir les étiquettes de ticks, comme ceci:
#ax is the axes instance
group_labels = ['control', 'cold treatment',
'hot treatment', 'another treatment',
'the last one']
ax.set_xticklabels(group_labels)
Je travaille toujours sur pourquoi votre exemple ci-dessus n'a pas fonctionné.
Cela fait longtemps que cette question a été posée. À compter d’aujourd’hui (matplotlib 2.2.2
) et après quelques lectures et essais, je pense que la meilleure façon/appropriée est la suivante:
Matplotlib a un module nommé ticker
that "contient des classes permettant de prendre en charge la localisation et le formatage de ticks entièrement configurables". Pour modifier une coche spécifique de l'intrigue, voici ce qui fonctionne pour moi:
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()
Caveat!x
est la valeur du tick et pos
est sa position relative dans l’ordre dans l’axe. Notez que pos
prend les valeurs commençant par 1
, et non dans 0
comme d'habitude lors de l'indexation.
Dans mon cas, j’essayais de formater le y-axis
d’un histogramme avec des valeurs en pourcentage. mticker
a une autre classe nommée PercentFormatter
qui peut le faire facilement sans avoir à définir une fonction distincte comme auparavant:
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()
Dans ce cas, xmax
est la valeur de donnée qui correspond à 100%. Les pourcentages sont calculés sous la forme x / xmax * 100
, c'est pourquoi nous corrigeons xmax=1.0
. De plus, decimals
est le nombre de décimales à placer après le point.
Cela fonctionne aussi dans matplotlib 3:
x1 = [0,1,2,3]
squad = ['Fultz','Embiid','Dario','Simmons']
plt.xticks(x1, squad, rotation=45)
Si vous ne travaillez pas avec fig
et ax
et que vous souhaitez modifier toutes les étiquettes (par exemple, pour la normalisation), vous pouvez procéder comme suit:
labels, locations = plt.yticks()
plt.yticks(labels, labels/max(labels))