Зміна "частоти галочок" на осі x або y в matplotlib?


477

Я намагаюся виправити, як python розміщує мої дані.

Сказати

x = [0,5,9,10,15]

і

y = [0,1,2,3,4]

Тоді я б зробив:

matplotlib.pyplot.plot(x,y)
matplotlib.pyplot.show()

і клітинки осі x будуються за інтервалом 5. Чи є спосіб, щоб він показав інтервали 1?


6
Хоча кліщі тут є відповідним словом, зміна кліщів на розмір кроку, безумовно, допоможе більше новачків у цьому питанні.
Сіббс Азартні ігри

9
Питання, що пов'язані між собою: stackoverflow.com/questions/6682784/… та чудове рішення:pyplot.locator_params(nbins=4)
Д-р Ян-Філіп Геркк

Здається, nbins застаріло в matplotlib2.x, на жаль
jeremy_rutman

Відповіді:


583

Ви можете чітко встановити, де потрібно поставити галочки за допомогою plt.xticks:

plt.xticks(np.arange(min(x), max(x)+1, 1.0))

Наприклад,

import numpy as np
import matplotlib.pyplot as plt

x = [0,5,9,10,15]
y = [0,1,2,3,4]
plt.plot(x,y)
plt.xticks(np.arange(min(x), max(x)+1, 1.0))
plt.show()

( np.arangeвикористовувалася замість rangeфункції Python на всякий випадок min(x)і max(x)є плаваючими елементами замість ints.)


Функція plt.plot(або ax.plot) автоматично встановлює значення за замовчуванням xта yобмеження. Якщо ви хочете зберегти ці межі та просто змінити ступінь розмітки галочок, ви можете використати ax.get_xlim()для виявлення, які межі Matplotlib вже встановлено.

start, end = ax.get_xlim()
ax.xaxis.set_ticks(np.arange(start, end, stepsize))

За замовчуванням форматор галочок повинен виконати гідну роботу, округлюючи значення галочки до значної кількості значущих цифр. Однак, якщо ви хочете мати більше контролю над форматом, ви можете визначити власний формат. Наприклад,

ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%0.1f'))

Ось приклад для запуску:

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

x = [0,5,9,10,15]
y = [0,1,2,3,4]
fig, ax = plt.subplots()
ax.plot(x,y)
start, end = ax.get_xlim()
ax.xaxis.set_ticks(np.arange(start, end, 0.712123))
ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%0.1f'))
plt.show()

72
Чи немає способу змусити його все-таки вирішити, що це власні обмеження, а просто змінити розмір кроку? Цей спосіб не дуже хороший, якщо хв чимось на зразок 3523.232512!
Короне

3
@Corone, Минув час, коли ви запитали, але я опублікував відповідь нижче, що дозволяє легко контролювати розмір кроку, використовуючи при цьому автоматичне визначення меж.
jthomas

3
Зверніть увагу , що +1в plt.xticks(np.arange(min(x), max(x)+1, 1.0))потрібний , щоб показати останню галочку.
Алекс Віллісон

1
Так, np.arange(start, stop)створює значення в напіввідкритому інтервалі [start, stop), включаючи, startале виключаючи stop. Тому я max(x)+1переконався, що max(x)включено.
unutbu

4
є еквівалент для дати, наприклад plt.xticks(np.arange(min(dates), max(dates)+0.1,0.1)? це здається лише сюжетом року
WBM

207

Інший підхід полягає у встановленні локатора осей:

import matplotlib.ticker as plticker

loc = plticker.MultipleLocator(base=1.0) # this locator puts ticks at regular intervals
ax.xaxis.set_major_locator(loc)

Існує кілька різних типів локатора, залежно від ваших потреб.

Ось повний приклад:

import matplotlib.pyplot as plt
import matplotlib.ticker as plticker

x = [0,5,9,10,15]
y = [0,1,2,3,4]
fig, ax = plt.subplots()
ax.plot(x,y)
loc = plticker.MultipleLocator(base=1.0) # this locator puts ticks at regular intervals
ax.xaxis.set_major_locator(loc)
plt.show()

7
Це не працює, як очікувалося. Зокрема, при використанні дат не використовуються відповідні дати.
Кріс Фоннесбек

35
Під час використання дат слід використовувати методи в модулі matplotlib.dates. Наприкладmatplotlib.dates.AutoDateLocator()
robochat

3
Це працювало, як і очікувалося, для мене, з датами. Це рішення набагато простіше, ніж прийняте.
Пабло Суу

Що base=1.0насправді означає / робити?
javadba

base = 1.0 означає, що знайдеться локатор для кожного цілого числа. У документації зазначено, що MultipleLocator "Встановлює галочку на кожне ціле число, кратне бази в межах інтервалу перегляду". Тож якщо base = 2, то буде встановлена ​​галочка для парних чисел, і я думаю, що ви можете поставити base = 2.5.
robochat

124

Мені подобається таке рішення (з кулінарної книги Matplotlib Plotting ):

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

x = [0,5,9,10,15]
y = [0,1,2,3,4]

tick_spacing = 1

fig, ax = plt.subplots(1,1)
ax.plot(x,y)
ax.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))
plt.show()

Це рішення дозволяє чітко контролювати відстань галочок через вказане число ticker.MultipleLocater(), дозволяє автоматично визначати межу та легко читати пізніше.


3
Спосіб це зробити без чіткого обчислення кліщів!
Зельфір Кальтшталь

4
Це та сама відповідь, що і ця . Через два роки ідентичної відповіді не має сенсу додавати ідентичну відповідь.
ВажливістьOfBeingErnest

6
Хороший улов. Я не визнав їх такими ж, коли розмістив відповідь. Але я вважаю, що цю презентацію зрозуміти трохи простіше.
jthomas

Довідка про книгу у цій відповіді також надає корисне джерело для отримання додаткової інформації.
Стівен К. Хоуелл

1
Це та сама відповідь, що і робота robochat, яка вийшла на три роки раніше.
MERose

90

У разі, якщо когось цікавить загальний однолінійний, просто дістаньте поточні кліщі та використовуйте його для встановлення нових кліщів шляхом відбору проб у кожного іншого кліща.

ax.set_xticks(ax.get_xticks()[::2])

3
Це єдина загальна відповідь для різних типів
галочок

2
Видаліть не цілі ax.set_xticks([tick for tick in ax.get_xticks() if tick % 1 == 0])
клічки

Багато детальних рішень вище, але я згоден, це найбільш стисло. Ви навіть можете витягти довжину ax.get_xticks () і встановити частоту нарізки на цю довжину, поділену на кількість необхідних кліщів.
Iain D

Я думаю, що це найкраща відповідь. Більшість інших відповідей занадто складні і важкі для застосування / узагальнення. Дякую!
Seankala

2
Це може лише зменшити кількість палиць, тоді як у питанні (і моїй цілі, як я це знайшов) було його збільшити.
Олексій Мартьянов

36

Це трохи хакі, але на сьогоднішній день найчистіший / найпростіший для розуміння приклад, який я знайшов для цього. Це з відповіді на SO тут:

Найпростіший спосіб приховати кожну п’яту мітку в кольоровій панелі matplotlib?

for label in ax.get_xticklabels()[::2]:
    label.set_visible(False)

Потім ви можете перевести петлю над мітками, встановивши їх видимими або не залежними від потрібної густини.

редагувати: зауважте, що іноді matplotlib встановлює мітки == '', тому це може виглядати так, що мітки немає, адже насправді вона є і просто нічого не відображає. Щоб переконатися, що ви переглядаєте фактичні видимі мітки, ви можете спробувати:

visible_labels = [lab for lab in ax.get_xticklabels() if lab.get_visible() is True and lab.get_text() != '']
plt.setp(visible_labels[::2], visible=False)

3
Це найбільш просте і загальне рішення. Невелике регулювання: зазвичай ax.get_xticklabels()[1::2]це мітки, які слід приховати.
jolvi

Це не працює з matplotlib.finance.candlestick2
BCR

@BCR, можливо, деякі xticklabel просто встановлені ''так, що, перебираючи їх, ви робите порожні невидимі xticklabels (що не вплине на візуалізацію, але може означати, що ви не тягнете правильні мітки). Ви можете спробувати: vis_labels = [label for label in ax.get_xticklabels() if label.get_visible() is True]; plt.setp(vis_labels[::2], visible==False)
choldgraf

15

Це стара тема, але я раз у раз натрапляю на це і виконую цю функцію. Це дуже зручно:

import matplotlib.pyplot as pp
import numpy as np

def resadjust(ax, xres=None, yres=None):
    """
    Send in an axis and I fix the resolution as desired.
    """

    if xres:
        start, stop = ax.get_xlim()
        ticks = np.arange(start, stop + xres, xres)
        ax.set_xticks(ticks)
    if yres:
        start, stop = ax.get_ylim()
        ticks = np.arange(start, stop + yres, yres)
        ax.set_yticks(ticks)

Одне застереження щодо керування кліщами, як це, - це те, що більше не сподобається інтерактивне автоматичне оновлення масштабу максимуму після доданого рядка. Тоді робіть

gca().set_ylim(top=new_top) # for example

і знову запустіть функцію перенастроювання.


11

Я розробив неелегантне рішення. Вважайте, що у нас є вісь X, а також список міток для кожної точки X.

Приклад:
import matplotlib.pyplot as plt

x = [0,1,2,3,4,5]
y = [10,20,15,18,7,19]
xlabels = ['jan','feb','mar','apr','may','jun']
Скажімо, що я хочу показувати клітинки мітками лише для 'feb' та 'jun'
xlabelsnew = []
for i in xlabels:
    if i not in ['feb','jun']:
        i = ' '
        xlabelsnew.append(i)
    else:
        xlabelsnew.append(i)
Добре, зараз у нас є підроблений список етикеток. Спочатку ми побудували оригінальну версію.
plt.plot(x,y)
plt.xticks(range(0,len(x)),xlabels,rotation=45)
plt.show()
Тепер модифікована версія.
plt.plot(x,y)
plt.xticks(range(0,len(x)),xlabelsnew,rotation=45)
plt.show()

6

якщо ви просто хочете встановити інтервал простого вкладиша з мінімальним котлом:

plt.gca().xaxis.set_major_locator(plt.MultipleLocator(1))

також легко працює при незначних кліщах:

plt.gca().xaxis.set_minor_locator(plt.MultipleLocator(1))

трохи приємного, але досить компактного


2
xmarks=[i for i in range(1,length+1,1)]

plt.xticks(xmarks)

Це працювало для мене

якщо ви хочете кліщів між [1,5] (від 1 до 5 включно), замініть

length = 5

1
фій, ти можеш просто написати xmarks = range(1, length+1, 1). майже впевнений, що розуміння списку є зайвим.
Ніл

2

Чиста реалізація Python

Нижче представлена ​​чиста реалізація потрібного функціонального пітону, який обробляє будь-який числовий ряд (int або float) з позитивними, негативними або змішаними значеннями та дозволяє користувачеві вказати бажаний розмір кроку:

import math

def computeTicks (x, step = 5):
    """
    Computes domain with given step encompassing series x
    @ params
    x    - Required - A list-like object of integers or floats
    step - Optional - Tick frequency
    """
    xMax, xMin = math.ceil(max(x)), math.floor(min(x))
    dMax, dMin = xMax + abs((xMax % step) - step) + (step if (xMax % step != 0) else 0), xMin - abs((xMin % step))
    return range(dMin, dMax, step)

Вибірка зразка

# Negative to Positive
series = [-2, 18, 24, 29, 43]
print(list(computeTicks(series)))

[-5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45]

# Negative to 0
series = [-30, -14, -10, -9, -3, 0]
print(list(computeTicks(series)))

[-30, -25, -20, -15, -10, -5, 0]

# 0 to Positive
series = [19, 23, 24, 27]
print(list(computeTicks(series)))

[15, 20, 25, 30]

# Floats
series = [1.8, 12.0, 21.2]
print(list(computeTicks(series)))

[0, 5, 10, 15, 20, 25]

# Step – 100
series = [118.3, 293.2, 768.1]
print(list(computeTicks(series, step = 100)))

[100, 200, 300, 400, 500, 600, 700, 800]

Використання зразка

import matplotlib.pyplot as plt

x = [0,5,9,10,15]
y = [0,1,2,3,4]
plt.plot(x,y)
plt.xticks(computeTicks(x))
plt.show()

Діаграма використання вибірки

Зауважте, що в осі x є цілі значення, всі рівномірно розміщені по 5, тоді як вісь y має інший інтервал ( matplotlibповедінка за замовчуванням, тому що тики не вказані).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.