You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Error on using add_vline with text annotation for data with date-time x axis #3065
Hi, I am trying to use the library for a simple visualisation for the first time, and I stumbled upon supposedly a bug trying to draw a vertical line with text annotation on a graph with a date-time x axis.
but this is the problem. Ideally we would need to rework this to use the (x|y)anchor attribute instead of trying to do math on the coordinates in the Python layer.
Reacted by Ondrej Zacha, Felipe Lema, tomshaffner, Enzo Guerrero-Araya, Aik Tarkhanyan, Nathan Raw, Carla Fernandez, Indresh Kumar, pavelbodrov, Jonno Schmidt and 27 more
@awrobel1 Thanks for your idea, I thought on using a rectangle as a replacement, where you would make both edges start at the limit of a single day. Not sure though that will completely imitate the vertical line, due to possible problem when zooming.
The above suggestion from @awrobel1 was great for me. In my case I simplified a tad with x=datetime.datetime(2021,5,27).timestamp() * 1000. No need to convert from a string first in this case.
Reacted by Nathan Raw, Alexander Zatey, Mateus Affonso Ferreira, pavelbodrov, Mo-Gul, Jeonghyun An, Randall Goodwin, Benoît Courty and Janosh Riebesell
Yes, after looking into this a bit more, the implementation assumes the data are types that can have arithmetic performed on them. It needs to do this in order to compute where to put the annotation. This bug probably got through because to compute where an annotation is placed, it only needs to find the minimum, maximum or mean of the extreme coordinate values. min and max are defined for strings, so dates don't break it for positions like 'left', 'right', etc., but I think the fact that it works is just luck: the strings often sort the same as the dates.
This points to 2 things that could be fixed at the higher level:
when doing arithmetic on data, operators should be chosen corresponding to the type of the axis: e.g., if the axis type is 'date' then the values should be converted to milliseconds before arithmetic is performed
rather than having anchored annotations only available when using add_hline and the like, maybe have them available when using add_shape? Then add_hline, etc. are just special cases of add_shape.
I have a rather weird problem that might be connected to this issue.
I deployed an app using streamlit (V'1.2.0')
I use Plotly (V'5.3.1') to create a plot in the app.
The plot is a timeline, and there is a vertical line in it.
Based on this bug, i caluclate the postion of the of the line the following:
end_time_prelim = datetime.strptime(df['end_time'].max(), "%Y-%m-%d %H:%M:%S").timestamp() * 1000
And then use this in
fig.add_vline(x=end_time_prelim)
This works fine when I run the code locally.
However, in the online version, the line is at a shifted different position and slightly shifted.
Not sure, but you might be having trouble with time zones? When you run time timestamp calculation I believe that its looking for the timestamp based on your current timezone. So locally, everything works intuitively, but when you host your code in the cloud you start running on a UTC server and the times all seem to jump.
If this is the problem you just need to make sure to adjust your line based on the difference between your current time and UTC, by adding/subtracting milliseconds or using timezone aware times.
Also, make sure your code can handle time shifts for daylight savings time if relevant!
Oh gosh, I don’t think we want to recommend Unix timestamps… we’d need them to be in milliseconds, and quite likely this will give time zone problems due to our weird backward-compatibility hacks on the plotlyjs side
Oh gosh, I don’t think we want to recommend Unix timestamps… we’d need them to be in milliseconds, and quite likely this will give time zone problems due to our weird backward-compatibility hacks on the plotlyjs side
You're right, I've tried changing the datetime to a unix timestamp but the time zone is not kept, resulting in an offset on the vertical lines.
Please look into this, it's been a bug for 3 years!
Reacted by Leonard Stimpfle, Renato, Alan Lee, 冯键, Rian Dolphin, herve-swish, nikolaikk and José
I'm also having the timezone issue mentioned by @PainOchoco here when using the unix workaround. The vertical lines are shifted by an hour. Any planned fix for this?
I found another workaround that fixes the time zone issue by using add_shape along with add_annotation (if you want an annotation). Example below:
# dt is of type datetime.datetime
fig.add_shape(
type="line",
x0=dt,
x1=dt,
y0=0,
y1=1,
yref="paper",
line=dict(
color="red",
width=1,
dash="dash",
),
)
fig.add_annotation(
x=dt,
y=1,
yref="paper",
text="This is an annotation",
showarrow=False,
textangle=-90,
font=dict(size=10),
xanchor="left",
yanchor="top",
)
The above suggestion from @awrobel1 was great for me. In my case I simplified a tad with x=datetime.datetime(2021,5,27).timestamp() * 1000. No need to convert from a string first in this case.
Importantly, plotly (very bizarrely) displays dates which are numerical timestamps in local time not UTC like everything else, so doing mydatetime.isoformat() is a bit better
Activity
nicolaskruchten commentedon Feb 5, 2021
Yep, definitely a bug! Thanks for the clear and reproducible report :)
I'm not immediately clear why we need to compute the midpoint of anything here
plotly.py/packages/python/plotly/plotly/shapeannotation.py
Line 58 in 03979d1
(x|y)anchorattribute instead of trying to do math on the coordinates in the Python layer.awrobel1 commentedon Feb 13, 2021
Hi @MR0205,
If you're looking for a temporary workaround, you can get the annotation to work by converting your
xvalue into milliseconds since epoch as follows:MR0205 commentedon Feb 18, 2021
@awrobel1 Thanks for your idea, I thought on using a rectangle as a replacement, where you would make both edges start at the limit of a single day. Not sure though that will completely imitate the vertical line, due to possible problem when zooming.
YukunYangNPF commentedon Mar 11, 2021
Following this too!
tomshaffner commentedon Jun 2, 2021
The above suggestion from @awrobel1 was great for me. In my case I simplified a tad with
x=datetime.datetime(2021,5,27).timestamp() * 1000. No need to convert from a string first in this case.nicholas-esterer commentedon Aug 2, 2021
Yes, after looking into this a bit more, the implementation assumes the data are types that can have arithmetic performed on them. It needs to do this in order to compute where to put the annotation. This bug probably got through because to compute where an annotation is placed, it only needs to find the minimum, maximum or mean of the extreme coordinate values.
minandmaxare defined for strings, so dates don't break it for positions like 'left', 'right', etc., but I think the fact that it works is just luck: the strings often sort the same as the dates.This points to 2 things that could be fixed at the higher level:
'date'then the values should be converted to milliseconds before arithmetic is performedadd_hlineand the like, maybe have them available when usingadd_shape? Thenadd_hline, etc. are just special cases ofadd_shape.ClaudiaBehnke86 commentedon Jan 5, 2022
Hi all,
I have a rather weird problem that might be connected to this issue.
I deployed an app using streamlit (V'1.2.0')
I use Plotly (V'5.3.1') to create a plot in the app.
The plot is a timeline, and there is a vertical line in it.
Based on this bug, i caluclate the postion of the of the line the following:
end_time_prelim = datetime.strptime(df['end_time'].max(), "%Y-%m-%d %H:%M:%S").timestamp() * 1000
And then use this in
fig.add_vline(x=end_time_prelim)
This works fine when I run the code locally.
However, in the online version, the line is at a shifted different position and slightly shifted.
Is this known?
Thanks a lot :-)
Not sure if helpful, but this would be the app:
https://share.streamlit.io/claudiabehnke86/tournamentcalculator/tourcalc/theapp.py
awrobel1 commentedon Jan 5, 2022
Hi @ClaudiaBehnke86,
Not sure, but you might be having trouble with time zones? When you run time timestamp calculation I believe that its looking for the timestamp based on your current timezone. So locally, everything works intuitively, but when you host your code in the cloud you start running on a UTC server and the times all seem to jump.
If this is the problem you just need to make sure to adjust your line based on the difference between your current time and UTC, by adding/subtracting milliseconds or using timezone aware times.
Also, make sure your code can handle time shifts for daylight savings time if relevant!
ClaudiaBehnke86 commentedon Jan 5, 2022
Yes, this makes a lot of sense :-D. Thanks for the hint!
alexrblohm commentedon Mar 24, 2022
Thanks for this! I had the same issue and it worked for me!
fzyzcjy commentedon Jun 15, 2022
Hi, how can I do similar things when
xare strings (labels) instead of dates or numbers?mateomontero01 commentedon Jul 21, 2022
This is still a problem for all categorial data on the x axis. Is there any solution for when x are strings?
6 remaining items
archmoj commentedon Feb 23, 2024
What happens if you convert the dates to UNIX timestamps?
alexcjohnson commentedon Feb 23, 2024
Oh gosh, I don’t think we want to recommend Unix timestamps… we’d need them to be in milliseconds, and quite likely this will give time zone problems due to our weird backward-compatibility hacks on the plotlyjs side
Dario-Mantegazza commentedon Feb 23, 2024
I will try to test it on the week of the 11th of March as before I don't have time. I hope I will remember XD
PainOchoco commentedon Jun 26, 2024
You're right, I've tried changing the datetime to a unix timestamp but the time zone is not kept, resulting in an offset on the vertical lines.
Please look into this, it's been a bug for 3 years!
rian-dolphin commentedon Apr 16, 2025
I'm also having the timezone issue mentioned by @PainOchoco here when using the unix workaround. The vertical lines are shifted by an hour. Any planned fix for this?
I found another workaround that fixes the time zone issue by using
add_shapealong withadd_annotation(if you want an annotation). Example below:implement pull request plotly#3731 and add tests to fix plotly#3065
admo1 commentedon Aug 14, 2025
I'm also having the timezone issue, any news on this issue ?
hugoalvarado commentedon Aug 22, 2025
Another workaround is to use vrect with the same value for x0 and x1 - visually the same as vline.
✅
❌
Allow for vlines on datetime axes with annotations by extending _mean…
Fix add_vline and add_hline with datetime axes
Fix _mean() to handle datetime values for shape annotations
pbeart commentedon Apr 15, 2026
Importantly, plotly (very bizarrely) displays dates which are numerical timestamps in local time not UTC like everything else, so doing
mydatetime.isoformat()is a bit better