2015-09-14 2 views
3

Я пытаюсь установить метки x tick, но позволяя matplotlib решать, где разместить метки. К сожалению, когда я устанавливаю метки x tick, matplotlib будет использовать строки ярлыков только для отметок, которые были отображены.Как установить метки x tick против фактических значений серии

Пример:

import matplotlib.pyplot as plt 

fig = plt.figure() 
ax = fig.add_subplot(111) 
xs = range(26) 
ys = range(26) 
ax.plot(xs, ys) 
ax.set_xticklabels(list('abcdefghijklmnopqrstuvwxyz')) 
plt.show() 

Это дает:

enter image description here

Это для меня довольно неинтуитивными; Я ожидаю, что метки будут соответствовать точкам, которые они показывают. (Однако я могу понять, что это поведение более полезно при построении нескольких серий, которые не используют одни и те же значения х.)

NB: Я не хочу, чтобы все 26 букв как тики. Скорее, я хочу только 6 (как предложил matplotlib), но эти 6 должны соответствовать их положениям. Затем это облегчит изменение размера фига без необходимости вручную пересчитывать новые метки меток.

Как я могу достичь желаемого результата?

+0

Это одна из причин, по которой 'set_ticklabels' является опасным, это pass-thru to FixedFormatter, который должен использоваться только с' FixedLocator'. – tacaswell

ответ

0

Вам необходимо назначить местоположение галочки перед метками. Самый простой способ получить желаемый результат для вашего примера - добавить ax.set_xticks(xs), прежде чем устанавливать метки тика.

import matplotlib.pyplot as pl 
fig = pl.figure() 
ax = fig.add_subplot(111) 
xs = range(26) 
ys = range(26) 
_ = ax.plot(xs, ys) 
alph = list('abcdefghijklmnopqrstuvwxyz') 
ax.set_xticks(xs) 
ax.set_xticklabels(alph) 
pl.savefig('ticklabels.png', dpi=300) 

enter image description here

Edit: Я хотел бы предложить следующие решения ваше желание для более общего решения:

from matplotlib.ticker import MaxNLocator 
import matplotlib.pyplot as pl 
import numpy as np 

alph = list('abcdefghijklmnopqrstuvwxyz') 
nticks = 8 

fig, ax = pl.subplots() 
xs = np.linspace(-10., 10., 100) 
ys = np.polyval([1., 2., 3.], xs) 

_ = ax.plot(xs, ys) 

ax.xaxis.set_major_locator(MaxNLocator(nticks)) 
ax.set_xticklabels(alph[::int(len(alph)/nticks)]) 

pl.savefig('ticklabels.png', dpi=300) 

Вы указываете количество тиков с MaxNLocator и карты их к алфавиту через нарезку.

Я не уверен, насколько надежным является MaxNLocator при возвращении именно необходимого количества тиков. Как упоминалось в комментариях, вы можете просто использовать len(ax.get_xticks()), чтобы получить количество тиков.

enter image description here

+0

Спасибо, Дэниэл. Однако, как я уже упоминал, я хотел бы сохранить интеллект, используемый для определения того, сколько клещей должно быть, и на каком расстоянии. В этом примере я бы не хотел, чтобы все 26 букв, всего 6, как в первом рисунке, но они должны быть подходящими. – cammil

+0

Вы хотите получить более общее решение, то есть сопоставить свой x-диапазон с буквами a-z, или вы всегда будете иметь эти 26 значений x? –

+0

Мне хотелось бы получить более общее решение. Значения по оси x и размеру графиков будут меняться. – cammil

2

Я думаю, наиболее подходящим решением является использование FuncFormatter, который позволит вам искать значение клещ этикетки вам нужно, и позволить Matplotlib определить позиции и количество тиков:

import matplotlib.pyplot as plt 
from matplotlib.ticker import FuncFormatter, MaxNLocator 
fig = plt.figure() 
ax = fig.add_subplot(111) 
xs = range(26) 
ys = range(26) 
labels = list('abcdefghijklmnopqrstuvwxyz') 


def format_fn(tick_val, tick_pos): 
    if int(tick_val) in xs: 
     return labels[int(tick_val)] 
    else: 
     return '' 
ax.xaxis.set_major_formatter(FuncFormatter(format_fn)) 
ax.xaxis.set_major_locator(MaxNLocator(integer=True)) 
ax.plot(xs, ys) 
plt.show() 

Это даст вам:

enter image description here

(спасибо Daniel Lenz для указателей и других предложений).

NB:

Как упомянуто tcaswell, xaxis.set_major_locator(MaxNLocator(integer=True)) используется для обеспечения тиков размещены на только целые значения.

+0

Я бы посоветовал также переустановить локатор мне «MaxNLocator» с 'interger = True', переданным (или мутирующим существующий inplace) http://matplotlib.org/api/ticker_api.html#matplotlib.ticker. MaxNLocator, чтобы убедиться, что у вас никогда не заканчиваются тики, такие как '[1.0, 1.25, 1.5, 1.75, 2.0]', которые будут иметь первые 4 с надписью «b». – tacaswell

+0

, и это достаточно полезно, не могли бы вы поместить в PR, чтобы добавить версию этого в галерею mpl? – tacaswell

+0

уверен. добавлен запрос на растяжение # 5063. – cammil

Смежные вопросы