Как получить xticks с переменным расстоянием? - PullRequest
2 голосов
/ 22 апреля 2020

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

В настоящее время:

enter image description here

Желаемый пример:

axis:  ----------------------
ticks: c1  c3  ...
         c2  c4   ...

1 Ответ

2 голосов
/ 22 апреля 2020

Подход состоит в том, чтобы создавать второстепенные тики в чередующихся позициях и увеличивать их длину. Значение MultipleLocator из 2 для основных тиков ставит их каждые 2. Добавление MultipleLocator из 1 для второстепенных тиков заполняет пробелы, так как основные тики автоматически подавляют второстепенные тики в перекрывающихся позициях. Цвет галочек можно сделать светлее, чтобы получить больше контраста между галочками и метками.

Тот же подход будет работать, когда график будет сгенерирован через seaborn или pandas, при условии, что список явно указан. ярлыки могут быть предоставлены.

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

letters = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
N = 80
names = [letters[i // 26] + letters[i % 26] for i in range(N)]
values = np.random.binomial(100, 0.1, N)

cmap = plt.cm.get_cmap('rainbow')
colors = [cmap(i / N) for i in range(N)]
plt.bar(names, values, color=colors)
ax = plt.gca()
ax.xaxis.set_major_locator(ticker.MultipleLocator(2))
ax.xaxis.set_minor_locator(ticker.MultipleLocator(1))
ax.xaxis.set_minor_formatter(ticker.IndexFormatter(names))
ax.tick_params(axis='x', which='minor', length=15)
ax.tick_params(axis='x', which='both', color='lightgrey')
ax.autoscale(enable=True, axis='x', tight=True)

plt.show()

example plot

PS: Идея @ MadPhysicist по комментариям добавлять новые строки еще проще. Это выглядит немного иначе:

from matplotlib import pyplot as plt
import numpy as np

letters = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
N = 80
names = [('\n' if i % 2 == 1 else '') + letters[i // 26] + letters[i % 26] for i in range(N)]
values = np.random.binomial(100, 0.1, N)

cmap = plt.cm.get_cmap('rainbow')
colors = [cmap(i / N) for i in range(N)]
plt.bar(names, values, color=colors)
plt.gca().autoscale(enable=True, axis='x', tight=True)
plt.show()

plot using newlines

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...