Вы можете перебирать сгенерированные полосы. Их координата x и ширина говорят о том, где они расположены по оси x. Высота полосы дает значение y для метки. Позиции на оси x дадут диапазон, который можно выбрать из соответствующего столбца фрейма данных. Для позиции x метки можно использовать соответствующий год.
Следует проявлять осторожность, поскольку последнее значение может выйти за пределы официального диапазона последнего бара. Кроме того, увеличение поля y помогает уместить весь текст на графике.
import pandas as pd
df = pd.DataFrame({'year': range(1990, 2020, 4), 'name': [*'abcdefgh']})
ax = df.year.hist(cumulative=True)
for rect in ax.patches:
left = rect.get_x()
right = left + rect.get_width()
height = rect.get_height()
if rect == ax.patches[-1]: # make sure the last range is wide enough to include the last date
right += 1
df2 = df[(df['year'] >= left) & (df['year'] <= right)]
for year, name in zip(df2['year'], df2['name']):
ax.text(year, height, f'{name}\n', ha='left', va='center')
ax.margins(y=0.15) # we need more room for the last label
PS: To only write one label per bar, you could add a break
in the for
loop:
for year, name in zip(df2['year'], df2['name']):
ax.text(year, height, f'{name}\n', ha='left', va='center')
break
For the step plot, you could use:
import pandas as pd
df = pd.DataFrame({'year': range(1990, 2020, 4), 'name': [*'abcdefgh']})
ax = df.reset_index().plot(x='year', y='index', drawstyle="steps", legend=False)
for ind, (year, name) in enumerate(zip(df['year'], df['name'])):
ax.text(year, ind, f' {name}', ha='left', va='center')
пример шагового графика