Zmodyfikuj tekst etykiety kleszcza


216

Chcę wprowadzić zmiany w kilku wybranych etykietach zaznaczenia na wykresie.

Na przykład, jeśli zrobię:

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

rozmiar czcionki i orientacja etykiety zaznaczenia zostały zmienione.

Jeśli jednak spróbujesz:

label.set_text('Foo')

etykieta wyboru nie jest modyfikowana. Również jeśli zrobię:

print label.get_text()

nic nie jest drukowane.

Oto trochę więcej dziwności. Kiedy spróbowałem:

 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()

Drukowane są tylko puste ciągi, ale wykres zawiera znaczniki oznaczone jako „0,0”, „0,5”, „1,0”, „1,5” i „2,0”.


Czy możesz podać fabułę użytą do uzyskania etykiety?
Claudio

Dostajesz puste etykiety, ponieważ nie narysowałeś jeszcze płótna. Jeśli zadzwonisz draw()przed próbą wydrukowania etykiet, otrzymasz to, czego oczekujesz. Ustawienie poszczególnych etykiet kleszczy jest niestety trudniejsze (dzieje się tak, że lokalizator i formatyzator kleszczy nie został zresetowany i nadpisuje rzeczy, gdy Ty set_text). Dodaję za chwilę przykład, jeśli ktoś mnie nie pobije. Jednak w tej chwili muszę złapać autobus.
Joe Kington

@JoeKington: Świetnie! Czekamy na Twoją poprawkę.
repoman

@repoman - Wygląda na to, że zbyt wcześnie rozmawiałem. To, co miałem na myśli, działa dla starszych wersji matplotlib, ale nie dla najnowszej wersji. Muszę trochę kopać. To powiedziawszy, nie powinno to być tak skomplikowane, jak to jest ...
Joe Kington

Odpowiedzi:


298

Zastrzeżenie: Chyba, że ​​znaczniki są już ustawione na ciąg znaków (jak to zwykle ma miejsce np. W przypadku wykresu pudełkowego), nie zadziała to z żadną wersją Matplotlib nowszą niż 1.1.0 . Jeśli pracujesz z obecnego mistrza github, to nie zadziała. Nie jestem jeszcze pewien, na czym polega problem ... Może to być niezamierzona zmiana lub może nie być ...

Zwykle zrobiłbyś coś według następujących zasad:

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()

wprowadź opis zdjęcia tutaj

Aby zrozumieć powód, dla którego musisz skakać przez tak wiele obręczy, musisz dowiedzieć się nieco więcej o strukturze matplotlib.

Matplotlib celowo unika wykonywania „statycznego” pozycjonowania kleszczy itp., Chyba że jest to wyraźnie nakazane. Założeniem jest, że będziesz chciał wchodzić w interakcje z fabułą, więc granice fabuły, tyknięć, naklejek itp. Będą się dynamicznie zmieniać.

Dlatego nie można po prostu ustawić tekstu danej etykiety kleszcza. Domyślnie jest on ponownie ustawiany przez Lokalizator osi i Formatyzator za każdym razem, gdy rysowany jest wykres.

Jeśli jednak Lokalizatory i Formatery są ustawione na statyczne ( FixedLocatori FixedFormatterodpowiednio), wówczas etykiety wyboru pozostają takie same.

To jest co set_*ticklabelslub ax.*axis.set_ticklabelsrobi.

Mamy nadzieję, że to nieco wyjaśnia, dlaczego zmiana indywidualnej etykiety kleszczy jest nieco skomplikowana.

Często to, co naprawdę chcesz zrobić, to po prostu przypisać określoną pozycję. W takim przypadku spójrz annotatezamiast tego.


10
to nie wydaje się działać z bieżącą wersją (1.20)!
Andrew Jaffe

1
Jeśli znaczniki są już ustawione na ciąg znaków, jak np. Na wykresie pudełkowym, nadal działa. Może to być oczywiste, ale ponieważ pierwsza linia odpowiedzi brzmi: nie działa ona na nowszych wersjach matplotlib, użytkownicy mogą ją całkowicie pominąć (początkowo tak zrobiłem). Może krótko o tym wspomnę.
joelostblom

2
myślę, że możesz to skondensować do plt.gca (). set_xticklabels (etykiety)
alexey,

co jeśli chcę, aby czcionka „testowania” była, boldpodczas gdy inni używają czcionki „light”. Czy jest na to sposób?
Steven

1
dla tych, którzy używają tego w notatniku jupyter, warto zauważyć, że fig.canvas.draw()jest to kluczowe
wander95

96

Można to również zrobić za pomocą pylab i 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


Jest to proste rozwiązanie i działa z pyplot 1.5.1. To powinno być ocenione pozytywnie.
wordmith

Chociaż pytanie nie wymagało tego, doceniam, że ten przykład pozwala ci ustawić lokalizację kleszczy jednocześnie z modyfikacją ich etykiet.
eklark

Od nowoczesnego dokumentów matplotlib : „pylab jest przestarzały, a jego użycie jest mocno odradzane z powodu zanieczyszczenia przestrzeni nazw. Zamiast tego użyj pyplot”.
Nathaniel Jones

93

W nowszych wersjach matplotlib, jeśli nie ustawisz etykiet kleszczy za pomocą szeregu strwartości, są one ''domyślnie (a gdy rysowany jest wykres, etykiety są po prostu wartościami kleszczy). Wiedząc o tym, uzyskanie pożądanej wydajności wymagałoby czegoś takiego:

>>> 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()

a wynik: wprowadź opis zdjęcia tutaj

a teraz, jeśli sprawdzisz _xticklabels, nie są już grupą ''.

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

Działa w wersjach od 1.1.1rc1do bieżącej wersji 2.0.


Dzięki, to była odpowiedź, której szukałem. Najczystsze rozwiązanie IMO; po prostu podaj set_xticklabelsmieszaną listę ciągów znaków i zaznacz obiekty.
Luke Davis,

Należy pamiętać, że jeśli etykiety znaczników są ustawione jako ints, spowoduje to zmianę ich na zmiennoprzecinkowe. Łatwo pracował, ale warto zauważyć.
ApproachingDarknessFish

Ten działał ( ax.get_xticks().tolist()). Najczęściej głosowane rozwiązanie nie ( ax.get_xtickslabels()). Jakoś nie było w stanie wyodrębnić etykiet przed plt.show()ekscytacją, chociaż użyłem fig.canvas.draw()zgodnie z sugestią.
CypherX,

FYI, z nowoczesnych dokumentów matplotlib : „pylab jest przestarzały, a jego użycie jest zdecydowanie odradzane z powodu zanieczyszczenia przestrzeni nazw. Zamiast tego użyj pyplot”.
Nathaniel Jones

17

Minęło trochę czasu, odkąd zadano to pytanie. Na dzień dzisiejszy ( matplotlib 2.2.2) i po kilku lekturach i próbach uważam, że najlepszym / właściwym sposobem jest:

Matplotlib ma moduł o nazwie ticker, która „zawiera klasy do wsparcia całkowicie konfigurowalnym lokalizowania kleszcza i formatowania” . Aby zmodyfikować konkretny tik z wykresu, dla mnie działa:

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()

Histogram z losowymi wartościami z rozkładu normalnego

Zastrzeżenie! xjest wartością tik i posjest jego względną pozycją w kolejności w osi. Zauważ, że poswartości zaczynają się od 1, a nie 0jak zwykle podczas indeksowania.


W moim przypadku próbowałem sformatować y-axishistogram za pomocą wartości procentowych. mtickerma inną klasę o nazwie, PercentFormatterktóra może to zrobić łatwo bez potrzeby definiowania oddzielnej funkcji jak poprzednio:

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()

Histogram z losowymi wartościami z rozkładu normalnego

W tym przypadku xmaxjest to wartość danych odpowiadająca 100%. Wartości procentowe są obliczane jako x / xmax * 100, dlatego naprawiamy xmax=1.0. Ponadto decimalsjest liczbą miejsc dziesiętnych do umieszczenia po kropce.


12

Klasa axes ma funkcję set_yticklabels, która pozwala ustawić etykiety znaczników, w następujący sposób:

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

ax.set_xticklabels(group_labels)

Nadal pracuję nad tym, dlaczego powyższy przykład nie zadziałał.


3
Ale chcę zmienić tylko jedną etykietę. Powyższa sztuczka wymaga wyodrębnienia wszystkich etykiet kleszczy i ustawienia żądanej na nową wartość. Ale jak mogę wyodrębnić etykiety zaznaczenia, gdy label.get_text () nic nie zwraca?
repoman

11

To działa:

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

Działa to również w Matplotlib 3:

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

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

5

Jeśli nie współpracujesz figi axchcesz zmodyfikować wszystkie etykiety (np. W celu normalizacji), możesz to zrobić:

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

1

Spróbuj tego :

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

-4

możesz to zrobić:

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

draw()

Czy ktoś może wyjaśnić, dlaczego ta odpowiedź jest tak mocno oceniana?
Hlynur Davíð Hlynsson

@ HlynurDavíðHlynsson Myślę, że tak naprawdę nie ma to nic wspólnego z tym pytaniem. Cóż, może z pewną edycją ... Edytuj to, jeśli możesz odnieść się do pytania. ;)
loved.by.Jesus
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.