zmniejszenie liczby punktów na działce

160

Mam zbyt wiele tików na moim wykresie i zderzają się one ze sobą.

Jak mogę zmniejszyć liczbę kleszczy?

Na przykład mam kleszcze:

1E-6, 1E-5, 1E-4, ... 1E6, 1E7

Chcę tylko:

1E-5, 1E-3, ... 1E5, 1E7

Próbowałem bawić się z LogLocator, ale nie byłem w stanie tego rozgryźć.

jlconlin
źródło

Odpowiedzi:

266

Alternatywnie, jeśli chcesz po prostu ustawić liczbę taktów, pozwalając matplotlib na ich pozycjonowanie (obecnie tylko z MaxNLocator), jest pyplot.locator_params,

pyplot.locator_params(nbins=4)

Możesz określić konkretną oś w tej metodzie, jak wspomniano poniżej, domyślnie są to:

# To specify the number of ticks on both or any single axes
pyplot.locator_params(axis='y', nbins=6)
pyplot.locator_params(axis='x', nbins=10)
bgamari
źródło
27
To była świetna sugestia, ponieważ możliwość określenia pyplot.locator_params(axis = 'x', nbins = 4)(lub axis = 'y') uczyniła proces naprawdę prostym. Dzięki @bgamari!
benjaminmgross
8
W przypadku skali logarytmicznej to działało numtickszamiastnbins
meduz
1
@bgamari, czy mógłbyś dodać numticksrozwiązanie dla wykresów logarytmicznych, jak wskazał @meduz?
Løiten
7
To nie wydaje się umieszczać etykiet tam, gdzie powinny. Na przykład, jeśli oryginalne etykiety znaczników są, [0, 1, ..., 99]a teraz jeden zestaw nticks=10, to nowe rzadkie etykiety zostaną umieszczone dziesięć razy dalej od siebie wzdłuż osi, tj. Teraz 1będą siedzieć tam 9, 2gdzie 19było , gdzie było ... i 9gdzie 99było.
Vim
2
Sprawdź wyniki, zanim zaufasz tej metodzie. @Vim jest poprawne. Wartości ticka zostaną umieszczone nieprawidłowo.
David J.
53

Jeśli ktoś nadal wyświetla tę stronę w wynikach wyszukiwania:

fig, ax = plt.subplots()

plt.plot(...)

every_nth = 4
for n, label in enumerate(ax.xaxis.get_ticklabels()):
    if n % every_nth != 0:
        label.set_visible(False)
Katerina
źródło
7
To faktycznie zadziałało w porównaniu ze wszystkimi innymi odpowiedziami, które nic nie dały. dzięki :)
faizan
Dobra robota. Znalezienie tego zajęło mi trochę czasu, ale zrobiło to, co chciałem.
Jan
Dziękuję, to gwarantuje, że pozostałe etykiety znajdują się we właściwych miejscach. Dodatkowym krokiem, który poprawiłby tę odpowiedź, jest również usunięcie znacznika wyboru.
David J.
Świetna prosta odpowiedź - nie zaskoczyła żadna niestandardowa metoda znana społeczności SO. To byłby cenny dodatek do lib?
jabberwocky
32

Aby rozwiązać ten problem i dostosowywania wyglądu kleszczy, zobacz Tick lokalizatory instrukcji na stronie matplotlib

ax.xaxis.set_major_locator(plt.MaxNLocator(3))

Ustawiłby całkowitą liczbę taktów na osi X na 3 i równomiernie rozłożyłby ją na osi.

Jest też fajny tutorial na ten temat

Prageeth Jayathissa
źródło
Wybierz tylko pierwsze 3 indeksy z datą i godziną. kiedy zdobędziesz topór od pand.DataFrame.plot ax = df.plot()
Mithril
@Mithril przepraszam, nie do końca rozumiem twój komentarz. Czy mógłbyś to rozwinąć?
Prageeth Jayathissa
Jeśli mam df ( pandas.DataFrame) z indeksem datetime [2019-01-01, ... 2019-11-01], call ax = df.plot(), zwróć obiekt figury. ax.xaxis.set_major_locator(plt.MaxNLocator(3)) tylko połączenie pokaż pierwsze 3 indeksy [2019-01-01, 2019-01-02, 2019-01-03].
Mithril
1
@Mithril, df.plot()często wyświetla znak, minor_locatorwięc możesz spróbować ax1.xaxis.set_minor_locator(plt.MaxNLocator(3)). Pamiętaj również, aby zastąpić 3liczbę ticków, które chcesz wyświetlić. W przypadku serii pand polecam import matplotlib.dates as mdatesi biegam ax.xaxis.set_minor_locator(mdates.MonthLocator(interval = 1))zax.xaxis.set_minor_formatter(mdates.DateFormatter('%m-%Y'))
Prageeth Jayathissa
20

Istnieje set_ticks()funkcja dla obiektów osi.

André Caron
źródło
4
To zadziałałoby, gdybym wiedział z góry, jakich kleszczy chcę. Podany powyżej przykład był tylko przykładem. Nie wiem, czym są kleszcze, po prostu wiem, że chcę ich mniej, tj. Co drugi.
jlconlin
10
Możesz najpierw wywołać get_xticks()lub get_yticks()najpierw dla obiektu axes, edytować w razie potrzeby, a następnie przekazać listę z powrotem do set_ticks().
user812786
4
Nie mam set_ticks(), ale mam set_xticks()i set_yticks(). Są to atrybuty obiektów osi, a nie osi. Może to się zmieniło w ciągu ostatnich kilku lat.
Gauthier
2
Nie jestem pewien, czy powinienem, niektórzy ludzie uznali twoją odpowiedź za przydatną i tylko dlatego, że jest inna dla mnie, nie oznacza, że ​​jest dla wszystkich.
Gauthier
1
Przykład bardzo pomógłby uczynić tę odpowiedź użyteczną.
Richard
10

na wypadek, gdyby ktoś nadal tego potrzebował, a ponieważ nic tutaj naprawdę nie działało dla mnie, wymyśliłem bardzo prosty sposób, który zachowuje wygląd wygenerowanego wykresu „tak jak jest”, jednocześnie ustalając liczbę taktów na dokładnie N:

import numpy as np
import matplotlib.pyplot as plt

f, ax = plt.subplots()
ax.plot(range(100))

ymin, ymax = ax.get_ylim()
ax.set_yticks(np.round(np.linspace(ymin, ymax, N), 2))
raphael
źródło
2
Musiałem nieco zmodyfikować ostatnią linię, aby ax.set_yticks(np.linspace(int(ymin), int(ymax), N), 2)
zwracała
@NickSettje nadal pływa ze mną!
Mohd
4

Rozwiązanie podane przez @raphael jest proste i całkiem pomocne.

Mimo to wyświetlane etykiety znaczników nie będą wartościami próbkowanymi z pierwotnej dystrybucji, ale z indeksów tablicy zwróconej przez np.linspace(ymin, ymax, N).

Aby wyświetlić N wartości w równych odstępach od oryginalnych etykiet znaczników, użyj tej set_yticklabels()metody. Oto fragment osi y z etykietami liczb całkowitych:

import numpy as np
import matplotlib.pyplot as plt

ax = plt.gca()

ymin, ymax = ax.get_ylim()
custom_ticks = np.linspace(ymin, ymax, N, dtype=int)
ax.set_yticks(custom_ticks)
ax.set_yticklabels(custom_ticks)
Tantris
źródło
Brawa za tę niezłą poprawkę!
Mohd
2

Gdy używana jest skala logarytmiczna, liczbę głównych taktów można ustalić za pomocą następującego polecenia

import matplotlib.pyplot as plt

....

plt.locator_params(numticks=12)
plt.show()

Wartość ustawiona na numticksokreśla liczbę taktów osi, które mają być wyświetlane.

Podziękowania dla posta @ bgamari za wprowadzenie locator_params()funkcji, ale nticksparametr generuje błąd, gdy używana jest skala dziennika.

Ébe Isaac
źródło
Pytanie i odpowiedź dotyczą poprzedniego matplotlib, czyli 1, a ty odnosisz się do 2.
Dawid Laszuk