Изменить текст метки


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

Предостережение: если тиклэйблы уже не установлены в строку (как это обычно имеет место, например, в блокпосте), это не будет работать с любой версией 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
для тех, кто использует это в ноутбуке Jupyter, может быть полезно отметить, что fig.canvas.draw()это крайне важно
— wander95

96

Можно также сделать это с pylab и 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. Это должно быть проголосовано.
— Wordsmith

Хотя этот вопрос не задавался этим вопросом, я ценю, что этот пример позволяет вам установить местоположение галочек одновременно с изменением их меток.
— экларк

Из современных документов 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смешанный список строк и тиковых объектов.
— Люк Дэвис

Имейте в виду, что если метки тиков установлены как целые, это изменит их на плавающие. Легко обходится, но стоит отметить.
— Приближается к

Этот работал ( ax.get_xticks().tolist()). Решение с наибольшим количеством голосов не ( ax.get_xtickslabels()). Каким-то образом он не смог извлечь ярлыки до того, как plt.show()был извинен, хотя я использовал, fig.canvas.draw()как предлагалось.
— CypherX

К вашему сведению, из современных документов 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

Класс axes имеет функцию 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 () ничего не возвращает?
— repoman

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)

федералы


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


-4

ты можешь сделать:

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

draw()

Может кто-нибудь объяснить, почему этот ответ так сильно опущен?
— Хлынур Давид Хлинссон

@ HlynurDavíðHlynsson Я думаю, что это не имеет никакого отношения к вопросу. Ну, может быть, с некоторым редактированием ... Пожалуйста, отредактируйте его, если вы захотите связать это с вопросом. ;)
— love.by.Iesus
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.