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

1

Я пытаюсь построить линейный график и тепловую карту на двухосевом графике. Это то, что я получаю:

Изображение 174551

Как вы можете видеть, линейный график не привязан к xticks из-за наличия карты нагрева, которая центрирует стрелки. Как перенести линейный график вправо на 0,5, чтобы точки данных на линейном графике правильно соответствовали xticks?

Ниже мой код:

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

data1 = np.random.random((10, 10))
data2 = np.random.random((10))

f, ax = plt.subplots(figsize=(11, 9))
plt.tick_params(bottom='on')
ax = sns.heatmap(data1, cmap=sns.color_palette("Greens", 5))
ax2 = plt.twinx()
sns.lineplot(data=data2, linewidth=5, ax=ax2)
ax.axis('tight')

plt.show()
  • 0
    Ответ Bazingaa ниже определенно решит вашу проблему. Тем не менее, в будущем, если вы хотите, чтобы ваши графики выглядели определенным образом, вы должны строить их таким образом с самого начала . Не позволяйте matplotlib или seaborn выбирать, какими должны быть x-данные ваших строк. Укажите данные x, когда вы строите линии в первую очередь .
  • 0
    @PMende: Под вопросом находились центрированные x-метки, установленные тепловой картой. Мне лично нравятся центрированные галочки для тепловой карты, так как они представляют данную квадратную сетку уникально, а не имеют галочки по краям
Показать ещё 2 комментария
Теги:
matplotlib
seaborn

2 ответа

4
Лучший ответ

Ниже приведен один из способов сделать это.

Объяснение: экземпляр с двумя осями ax2 имеет только одну строчку, построенную с использованием sns.lineplot. Сначала вы извлекаете этот объект line. Затем вы просто обновляете (сдвигаете) x-данные этой строки вправо на 0.5 как вы хотели. line.get_xdata() возвращает вам массив значений x, и вы просто добавляете 0.5 в векторном виде, а затем применяете изменения, используя line.set_xdata. Добавьте следующие строки после команды sns.lineplot().

line = ax2.lines[0] # get the line
line.set_xdata(line.get_xdata() + 0.5)

Изображение 174551

2

Проблема заключается не в линейном графике, а в тепловой карте, показывающей тики в неправильных положениях [*]. Вместо этого вы можете использовать график matplotlib imshow, где все работает правильно.

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

data1 = np.random.random((10, 10))
data2 = np.random.random((10))

f, ax = plt.subplots(figsize=(11, 9))
plt.tick_params(bottom='on')

im = ax.imshow(data1, cmap=plt.get_cmap("Greens",5), aspect="auto")
f.colorbar(im)

ax2 = plt.twinx()
sns.lineplot(data=data2, linewidth=5, ax=ax2)
ax.axis('tight')

plt.show()

Изображение 174551


[*] Под "неправильной позицией" я имею в виду, что тики не появляются в позиции на осях, которые, по-видимому, маркируются. То есть единицы данных тиков не идентичны значениям, указанным на этикетках.

В случае, если карта нагрева нанесена на ax, печать

print(*ax.get_xticklabels())

приводит к

Text(0.5, 0, '0') Text(1.5, 0, '1') Text(2.5, 0, '2') Text(3.5, 0, '3') Text(4.5, 0, '4') Text(5.5, 0, '5') Text(6.5, 0, '6') Text(7.5, 0, '7') Text(8.5, 0, '8') Text(9.5, 0, '9')

Здесь вы можете видеть, что первая метка метки позиционируется в x=0.5, но показывает '0' качестве метки. Т.е. все позиции сдвинуты на 0,5 по сравнению с их метками.

В случае imshow (после рисования графика, f.canvas.draw()), напечатанные ярлыки

Text(-2.0, 0, '-2') Text(0.0, 0, '0') Text(2.0, 0, '2') Text(4.0, 0, '4') Text(6.0, 0, '6') Text(8.0, 0, '8') Text(10.0, 0, '10')

Здесь метки и позиции согласованы.

  • 0
    Если я просто использую im = ax.imshow(data1, cmap=plt.get_cmap("Greens",5), aspect="auto") без рисования линии в вашем коде, отметки по-прежнему отображаются в тех же позициях, что и в график, созданный с использованием sns.heatmap , т. е. центрированные sns.heatmap
  • 0
    @ Базингаа Да, это неожиданно?
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню