1

I have the following data frame:

dates = [pd.Timestamp('2010-01-01T12:10:30'), pd.Timestamp('2010-01-01T12:10:35'), pd.Timestamp('2010-01-01T12:10:40')]
df = pd.DataFrame({'ref_date': dates, 'x': [1, 3, 2]}).set_index('ref_date')

How do I add each x-value as text on the plot? If the x-axis weren't a time series, then I could have looped through each value and use ax.text(), but I don't know how to do that when I have timestamps instead, i.e. I don't know how to calculate the (x, y) coordinate for the text.

sns.scatterplot(data=df)

EDIT: Is there a way we can dynamically make labels not overlap? For example, consider adding this extra point to the above df: pd.Timestamp('2010-01-01T12:10:30.001') and 1.03.

enter image description here

user270199
  • 905
  • 1
  • 6
  • 12

1 Answers1

1

Matplotlib (and Seaborn) uses the number of dates since the epoch to store date values. The function date2num can be used to convert datetime objects to this numeric representation:

import matplotlib
print(matplotlib.dates.date2num(pd.Timestamp('2010-01-01T12:10:30')))
#prints 14610.507291666667

To get the correct positions on the x axis for the text, this function can be used:

sp = sns.scatterplot(data=df)

for index, row in df.iterrows():
    sp.axes.text(matplotlib.dates.date2num(index), row['x'], row['x'], size='large')

enter image description here

werner
  • 13,518
  • 6
  • 30
  • 45
  • Thanks @werner. Is there a way we can dynamically move the position of the label, especially when two labels are overlapping each other? Please see the EDIT above including an example. – user270199 Jun 06 '21 at 09:55
  • There is a [question](https://stackoverflow.com/q/19073683/2129801) about the overlapping problem. Maybe one of the answers can help you? If not I would suggest to ask a new question, as your edit abot the overlapping labels is a bit unrelated to the original question about the timeseries issue. – werner Jun 06 '21 at 16:08