Я хотел бы перебирать подграфики, отображать данные и аннотировать подграфики либо с помощью функции text
, либо с помощью функции annotation
в matplotlib. Обе функции запрашивают координаты x и y для размещения текста или аннотаций. Я могу заставить это работать нормально, пока я не нанесу данные. Затем аннотации и текст прыгают повсюду, и я не могу понять, почему.
Моя установка выглядит примерно так, что создает хорошо выровненные аннотации без данных:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
fig, ax=plt.subplots(nrows=3, ncols=3, sharex=True)
fig.suptitle('Axes ylim unpacking error demonstration')
annotation_colors=["red", "lightblue", "tan", "purple", "lightgreen", "black", "pink", "blue", "magenta"]
for jj, ax in enumerate(ax.flat):
bott, top = plt.ylim()
left, right = plt.xlim()
ax.text(left+0.1*(right-left), bott+0.1*(top-bott), 'Annotation', color=annotation_colors[jj])
plt.show
Когда я добавляю случайные данные (или мои настоящие данные), аннотации прыгают:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
#Same as above but but with 9 random data frames plotted.
df_cols = ['y' + str(x) for x in range(1,10)]
df=pd.DataFrame(np.random.randint(0,10, size=(10,9)), columns=df_cols)
df['x']=range(0,10)
#Make a few columns much larger in terms of magnitude of mean values
df['y2']=df['y2']*-555
df['y5']=df['y5']*123
fig, ax=plt.subplots(nrows=3, ncols=3, sharex=True)
fig.suptitle('Axes ylim unpacking error demonstration')
annotation_colors=["red", "lightblue", "tan", "purple", "lightgreen", "black", "pink", "blue", "magenta"]
for jj, ax in enumerate(ax.flat):
ax.plot(df['x'], df['y'+str(jj+1)], color=annotation_colors[jj])
bott, top = plt.ylim()
left, right = plt.xlim()
ax.text(left+0.1*(right-left), bott+0.1*(top-bott), 'Annotation', color=annotation_colors[jj])
plt.show()
Это просто для демонстрации проблемы, которая, вероятно, вызвана моим непониманием того, как работают вызовы топора и фиги. Мне кажется, что координаты x и y вызова ax.text на самом деле могут относиться к координатам fig или чему-то подобному. Конечный результат намного хуже с моими фактическими данными!!! В этом случае некоторые из аннотаций оказываются на много миль выше реальных графиков и даже не находятся в координатах какой-либо из осей подграфиков. Другие полностью перекрываются! Что я недопонимаю?
Изменить для более подробной информации:
Я попробовал решение Стефа с использованием координат осей axes.text(0.1, 0.1, 'Annotation'...)
Я получаю следующий график, который по-прежнему показывает ту же проблему перемещения текста повсюду. Поскольку я запускаю этот пример со случайными числами, аннотации перемещаются случайным образом при каждом запуске, то есть они не просто смещаются на подграфиках с разными диапазонами осей (y2 и y5).
Вы можете указать местоположение текста в координатах осей (в отличие от координат данных, как вы сделали неявно):
ax.text(.1, .1, 'Annotation', color=annotation_colors[jj], transform=ax.transAxes)
Смотрите Учебник по трансформациям для получения дополнительной информации.
Так как же matplotlib знает, что есть что? Координаты осей просто находятся между 0 и 1, а нижний левый угол равен [0,0]?
да, см. таблицу в связанном учебнике
Спасибо - я неправильно закодировал свойство преобразования. Исправил это, и теперь это работает.
После редактирования я понял, что неправильно закодировал решение Стефа в своем ответе. Это работает, и именно transform=ax.transAxes устанавливает подпрограмму для распознавания координат осей, а не координат данных.