Как сделать так, чтобы текст оси y появлялся внутри графика при использовании координат данных в matplotlib? - PullRequest
3 голосов
/ 29 марта 2020

У меня есть график, где я отображаю максимальные и минимальные точки на графике разными цветами. Поскольку сюжет динамический c, иногда текст появляется прямо поверх ytick меток , что выглядит не очень хорошо. Я хочу сохранить ytick, поэтому я подумал о том, чтобы поместить текст внутри графика.
Однако моя ось x является переменной datetime, поэтому положение x, y находится между первый и второй xtick сбивает меня с толку.

Я попробовал решение здесь , но оно для всей оси.

На основе документации Я попробовал Координаты оси (0,0 слева внизу и 1,1 справа вверху), но проблема в том, что его трудно найти с правильной позицией пикселя, которая находится как внутри, так и сверху горизонтальных линий. Более того, я думаю, что будет трудно поддерживать , поскольку данные меняются каждый день.

Я хотел бы придерживаться координат данных , так как данные являются динамическими c.
Можно ли сделать это, используя координаты данных?

Пожалуйста, используйте следующий код, который я придумал для своей ситуации -

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.transforms as transforms

x = ['2020-03-01', '2020-03-02', '2020-03-03', '2020-03-04', '2020-03-05']
y = [1,2,3,4,5.8]
df = pd.DataFrame({'X': x, 'Y': y})

fig, ax = plt.subplots()
sns.lineplot(x='X', y='Y', data=df)
show_point = 5.7
ax.axhline(show_point, ls='dotted')
trans = transforms.blended_transform_factory(ax.get_yticklabels()[0].get_transform(), ax.transData)
ax.text('2020-03-01', show_point, color="red", s=show_point, transform=trans, ha="right", va="bottom")

show_point2 = 1.7
ax.axhline(show_point2, ls='dotted')
trans = transforms.blended_transform_factory(ax.get_yticklabels()[0].get_transform(), ax.transAxes)
ax.text(0.05, 0.15, color="red", s=show_point2, transform=trans, ha="center", va="bottom")

plt.show()

РЕДАКТИРОВАТЬ 1
Как это выглядит сейчас (на реальном графике) -
enter image description here
Ожидаемый результат - enter image description here

Ответы [ 2 ]

4 голосов
/ 29 марта 2020

Идея использования смешанной системы координат верна. Вы можете поместить текст в координату y в координатах данных и координату x в координатах осей.

trans = transforms.blended_transform_factory(ax.transAxes, ax.transData)
ax.text(0.01, show_point, show_point, color="red", transform=trans, ha="left", va="bottom")

Это конкретное смешанное преобразование даже встроено, поэтому вы также можете использовать

ax.text(0.01, show_point, show_point, color="red", transform=ax.get_yaxis_transform(),
        ha="left", va="bottom") 
2 голосов
/ 29 марта 2020

Вы можете избежать всех вещей преобразования оси, все еще работая в координатах данных, если вы используете matplotlib.axes.Axes.annotate, что-то вроде этого

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

x = ['2020-03-01', '2020-03-02', '2020-03-03', '2020-03-04', '2020-03-05']
y = [1,2,3,4,5.8]
df = pd.DataFrame({'X': x, 'Y': y})

fig, ax = plt.subplots()
sns.lineplot(x='X', y='Y', data=df)
show_point = 5.7
ax.axhline(show_point, ls='dotted')
ax.annotate(show_point, [ax.get_xticks()[0], show_point], va='bottom', 
            ha='right', color='red')

show_point2 = 1.7
ax.axhline(show_point2, ls='dotted')
ax.annotate(show_point2, [ax.get_xticks()[0], show_point2], va='bottom', 
            ha='right', color='red')

plt.show()

Это приведет к

enter image description here

...