Matplotlib - наложение линейного графика на гистограмму и выравнивание утиков - PullRequest
1 голос
/ 09 января 2020

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

Вот что у меня есть

import matplotlib.pyplot as plt
import numpy as np
group = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55]
amount1 = [967, 975, 1149, 1022, 852, 975, 1025, 1134, 994, 1057, 647, 1058]
amount2 = [286, 364, 111, 372, 333, 456, 258, 152, 400, 181, 221, 441]

f, (ax1, ax2) = plt.subplots(nrows = 1, ncols = 2, sharey=True, figsize = (17,8))
ax1_2 = ax1.twinx()

# y_pos
y_pos = np.arange(len(group))

# plot men
ax1.barh(y_pos, amount1, align = 'center')
ax1_2.plot(amount2, group, color = 'black', marker = 'o')

# ticks
ax1.set_yticks(y_pos)
ax1.set_yticklabels(group)
ax1.invert_xaxis()
ax1.yaxis.tick_right()

# padding
plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0.05, hspace=None)

plt.show()
plt.close()

Resulting graph

Я пытался установить тики, но гистограмма и линейный график, похоже, имеют совершенно разные представления об этом. Я также попытался построить графики на оси ax1, но затем линейный график выходит далеко за пределы гистограммы, и они вообще не выстраиваются. Я также пробовал ax1_2.set_yticks(ax1.get_yticks()), но с аналогичной проблемой.

Любая помощь будет признательна!

Ответы [ 2 ]

0 голосов
/ 09 января 2020

Вы можете построить как в ax1, так и удалить y_pos, потому что в конце оба они разделяют переменную group как координату y.

Затем вы можете добавить height к графику барха.

Здесь это код:

import matplotlib.pyplot as plt

group = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55]
amount1 = [967, 975, 1149, 1022, 852, 975, 1025, 1134, 994, 1057, 647, 1058]
amount2 = [286, 364, 111, 372, 333, 456, 258, 152, 400, 181, 221, 441]

f, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, sharey=True, figsize=(17, 8))

# plot men
a = ax1.barh(group, amount1, height=4)
ax1.plot(amount2, group, color='black', marker='o')

# ticks
ax1.set_yticks(group)
ax1.set_yticklabels(group)
ax1.invert_xaxis()
ax1.yaxis.tick_right()

# padding
plt.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=0.05,
                    hspace=None)

plt.show()
plt.close() 

И изображение с результатом:

enter image description here

0 голосов
/ 09 января 2020

Основная проблема в том, что ylim обеих осей не выровнены. y графика barh выглядит как 0, 1, 2, 3 до 11. Линейный график y изменяется от 0 до 55 с шагом 5. Чтобы выровнять их, вы можете просто сделать ax1_2.set_ylim([y * 5 for y in ax1.get_ylim()]).

Альтернативой может быть также использование ypos для линейного графика. Тогда ограничения можно просто скопировать: ax1_2.set_ylim(ax1.get_ylim()).

Вот пример кода, второй граф которого упущен для простоты:

import matplotlib.pyplot as plt
import numpy as np

group = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55]
amount1 = [967, 975, 1149, 1022, 852, 975, 1025, 1134, 994, 1057, 647, 1058]
amount2 = [286, 364, 111, 372, 333, 456, 258, 152, 400, 181, 221, 441]

f, ax1 = plt.subplots()
ax1_2 = ax1.twinx()

# y_pos
y_pos = np.arange(len(group))

# plot men
ax1.barh(y_pos, amount1, align='center', color='turquoise')
ax1_2.plot(amount2, group, color='crimson', marker='o')

ax1_2.set_ylim([y * 5 for y in ax1.get_ylim()])
# ticks
ax1.set_yticks(y_pos)
ax1.set_yticklabels(group)
ax1.yaxis.tick_right()
ax1.invert_xaxis()

plt.show()

resulting plot

Теперь на графике на 0, 10, 20 тиков темнее, чем на ax1_2. Просто позвоните ax1_2.set_yticks([]), чтобы удалить их.

PS: Еще один способ - забыть о ypos и использовать group только для оси у ax1. Затем необходимо адаптировать высоту стержней, например, к 4,5, поскольку теперь она измеряется в единицах group.

В коде:

ax1.barh(group, amount1, align='center', color='turquoise', height=4.5)
ax1_2.plot(amount2, group, color='crimson', marker='o')
ax1_2.set_ylim(ax1.get_ylim()) # no need for labels as the ticks have the same value
ax1.set_yticks(group)
ax1_2.set_yticks([]) 
ax1.yaxis.tick_right()
ax1.invert_xaxis()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...