Змінення тексту мітки


216

Я хочу внести деякі зміни до декількох вибраних міток у графіці.

Наприклад, якщо я це роблю:

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

розмір шрифту та орієнтація галочки міняються.

Однак якщо спробувати:

label.set_text('Foo')

мітка галочки не змінена. Також якщо я роблю:

print label.get_text()

нічого не друкується.

Ось ще кілька дивацтв. Коли я спробував це:

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

Друкуються лише порожні рядки, але сюжет містить тики, позначені як "0,0", "0,5", "1,0", "1,5" та "2,0".


Чи можете ви надати сюжет, який ви використовували для отримання етикетки?
Клаудіо

Ви отримуєте порожні етикетки, оскільки ви ще не намалювали полотно. Якщо ви подзвоните, draw()перш ніж спробувати надрукувати етикетки, ви отримаєте те, що очікуєте. Налаштувати окремі мітки галочок, на жаль, важче (якщо трапиться, що локатор та формат галочок не було скинуто, і це змінить речі, коли ви set_text). Я трохи додаю приклад, якщо хтось не переможе мене. Наразі я маю спіймати автобус.
Джо Кінгтон

@JoeKington: Чудово! З нетерпінням чекаю Вашого виправлення.
репоман

@repoman - Ну, схоже, я занадто рано заговорив. Що я мав на увазі, працює для старих версій matplotlib, але не для останньої версії. Мені потрібно трохи більше викопати. Коли вже було сказано, це не повинно бути таким складним, як це ...
Джо Кінгтон

Відповіді:


298

Caveat: Якщо тікетлики вже не встановлені на рядок (як це зазвичай відбувається, наприклад, у boxplot), це не працюватиме з будь-якою версією matplotlib, більш новою, ніж 1.1.0. Якщо ви працюєте з поточним майстром github, це не працюватиме. Я не впевнений, у чому проблема ще ... Це може бути ненавмисна зміна, а може не бути ...

Як правило, ви робите щось у цьому напрямку:

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

введіть тут опис зображення

Щоб зрозуміти причину, через яку вам потрібно перестрибувати стільки обручів, вам потрібно зрозуміти трохи більше про те, як структурується matplotlib.

Matplotlib навмисно уникає "статичного" позиціонування кліщів тощо, якщо прямо не вказано. Припущення полягає в тому, що ви хочете взаємодіяти з сюжетом, і тому межі сюжету, кліщі, галочки тощо будуть динамічно змінюватися.

Тому ви не можете просто встановити текст заданої мітки. За замовчуванням вона встановлюється за допомогою Локатора та Форматора осей кожного разу, коли малюється графік.

Однак якщо Локатори та Форматори встановлені статичними ( FixedLocatorі FixedFormatterвідповідно), то позначки галочок залишаються однаковими.

Це те, що set_*ticklabelsчи ax.*axis.set_ticklabelsробить.

Будемо сподіватися, що це стає трохи зрозумілішим, чому зміна окремої мітки галочки дещо складна.

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


10
це не працює з поточною версією (1.20)!
Ендрю Яффе

1
Якщо галочки вже встановлені на рядок, як, наприклад, у коробці, це все ще працює. Це може бути очевидним, але оскільки перший рядок відповіді полягає в тому, що він не працює на новіших версіях matplotlib, користувачі можуть його пропустити повністю (я це робив спочатку). Можливо, коротко згадайте про це.
joelostblom

2
Я думаю, ви можете звести його до plt.gca (). set_xticklabels (мітки)
alexey

що робити, якщо я хочу, щоб вага ваги "тестування" був, boldа інші використовують "легкий". Чи є спосіб це зробити?
Стівен

1
для тих, хто використовує це у зошиті з юпітером, можливо, виграє відзначення, що fig.canvas.draw()є надзвичайно важливим
блукайте95

96

Можна також зробити це за допомогою пілабу та 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


Це просте рішення і працює з pyplot 1.5.1. Це слід заохочувати.
wordmith

Хоча питання не ставив цього питання, я вдячний, що цей приклад дозволяє встановлювати розташування кліщів одночасно з зміною їх міток.
Екларк

З сучасних документів matplotlib : "pylab застарілий, і його використання сильно не рекомендується через забруднення простору імен. Замість цього використовуйте pyplot."
Натаніель Джонс

93

У нових версіях matplotlib, якщо ви не встановлюєте галочки з купою strзначень, вони є'' за замовчуванням (а коли графік малюється, мітки - це просто значення кліща). Знаючи це, для отримання потрібного результату знадобиться щось подібне:

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

і результат: введіть тут опис зображення

і тепер якщо ви перевірите _xticklabels, вони більше не бувають ''.

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

Він працює у версіях від 1.1.1rc1поточної версії 2.0.


Дякую, це відповідь, яку я шукав. Найчистіший розчин ІМО; просто надайте set_xticklabelsзмішаний список рядків і об'єктів галочок.
Люк Девіс

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

Цей працював ( ax.get_xticks().tolist()). Найбільш проголосоване рішення не ( ax.get_xtickslabels()). Якось не вдалося витягти етикетки до того, як plt.show()було виправдано, хоча я використовував, fig.canvas.draw()як було запропоновано.
CypherX

FYI, із сучасних документів matplotlib : "pylab застарів і його використання сильно не рекомендується через забруднення простору імен. Замість цього використовуйте pyplot."
Натаніел Джонс

17

Минув час, коли це питання було задано. Станом на сьогоднішній день (matplotlib 2.2.2 ) та після деяких читань та випробувань, я вважаю, що найкращим / правильним способом є наступне:

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

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

Гістограма зі випадковими значеннями від нормального розподілу

Кава! x- значення кліща і posйого відносне положення в порядку в осі. Зверніть увагу, що posзначення приймаються починаючи з 1, а не 0як зазвичай при індексації.


У моєму випадку я намагався відформатувати y-axisгістограму з відсотковими значеннями. mtickerмає ще один клас з іменем, PercentFormatterякий може це легко зробити без необхідності визначати окрему функцію, як раніше:

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

Гістограма зі випадковими значеннями від нормального розподілу

У цьому випадку xmax- значення даних, що відповідає 100%. Відсотки обчислюються як x / xmax * 100, тому ми і фіксуємо xmax=1.0. Також decimals- це кількість десяткових знаків після точки.


12

Клас осей має функцію set_yticklabels, яка дозволяє встановлювати мітки, наприклад:

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

ax.set_xticklabels(group_labels)

Я досі працюю над тим, чому ваш приклад вище не працював.


3
Але я хочу лише змінити одну мітку. Наведений вище трюк вимагає витягнути всі мітки та встановити потрібне нове значення. Але як я можу витягнути мітки, коли label.get_text () нічого не повертає?
репоман

11

Це працює:

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

Це також працює в matplotlib 3:

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

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

5

Якщо ви не працюєте figі axхочете змінити всі мітки (наприклад, для нормалізації), ви можете зробити це:

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

1

Спробуйте це :

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

-4

Ви можете зробити:

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

draw()

Чи може хтось пояснити, чому ця відповідь так сильно заперечується?
Hlynur Davíð Hlynsson

@ HlynurDavíðHlynsson Я думаю, це насправді не має нічого спільного з питанням. Ну, можливо, з деяким редагуванням ... Будь ласка, відредагуйте його, якщо ви хочете пов’язати це питання. ;)
loved.by.Jesus
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.