-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Issue #3755 Bug Fix for: Shapes and Annotations With yref Parameter Not Drawing on Correct Axis #4177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue #3755 Bug Fix for: Shapes and Annotations With yref Parameter Not Drawing on Correct Axis #4177
Conversation
...bug on the previous commit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@zfoltz this looks great - thanks!! Very nice tests 🎉
💃 Will merge once the tests pass.
Hmm the doc build test looks like it might point to a bug here?
import plotly.express as px df = px.data.iris() fig = px.scatter(df, x="sepal_length", y="sepal_width", facet_col="species") # sources of images sources = [ "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Iris_setosa_var._setosa_%282595031014%29.jpg/360px-Iris_setosa_var._setosa_%282595031014%29.jpg", "https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Iris_versicolor_quebec_1.jpg/320px-Iris_versicolor_quebec_1.jpg", "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Iris_virginica_2.jpg/480px-Iris_virginica_2.jpg", ] # add images for col, src in enumerate(sources): fig.add_layout_image( row=1, col=col + 1, source=src, xref="x domain", yref="y domain", x=1, y=1, xanchor="right", yanchor="top", sizex=0.2, sizey=0.2, ) fig.show()
Gives the error:
ValueError:
Invalid value of type 'builtins.str' received for the 'yref' property of layout.image
Received value: 'y domain domain'
Also we should add a changelog entry for this fix 🎉
Yes, you are right! From the looks of it, I think there is a pretty straightforward fix, I'll try to verify and update later today. Thanks for taking a look at this!
...ithub.com/zfoltz/plotly.py into axis_spanning_layout_object_xref_yref_bug
...ithub.com/zfoltz/plotly.py into axis_spanning_layout_object_xref_yref_bug
The bug showing in the build-doc is fixed and I updated changelog! 👍
- I have added a CHANGELOG entry if fixing/changing/adding anything substantial.
endursa
commented
May 11, 2023
I tried the bugfix, and while the hline is now working if set to yref=y3 for example, an annotation_text is not displayed at all!
Hey @endursa, can you post what you are working with? I tried to reproduce the error you mentioned but the following test I ran is working correctly:
import plotly.graph_objects as go
fig = go.Figure()
fig.add_traces(go.Scatter(x=[1,2,3],y=[1,2,3], yaxis='y',name='y1 trace'))
fig.add_traces(go.Scatter(x=[1,2,3],y=[3,2,1], yaxis='y2',name='y2 trace'))
fig.add_traces(go.Scatter(x=[2,3,4],y=[4,4,3], yaxis='y3',name='y3 trace'))
fig.add_hline(y=3, yref='y3', label={'text':'hline annotation text on y3'})
fig.add_hrect(y0=3.5, y1=4, annotation_text='hrect annotation text on y3', yref='y3')
fig.update_layout(
xaxis=dict(domain=[0, 0.9]),
yaxis=dict(title="yaxis1 title"),
yaxis2=dict(title="yaxis2 title",overlaying="y",side="right",position=0.9,),
yaxis3=dict(title="yaxis3 title",overlaying="y",side="right",position=1,)
)
fig.show()
This results in the following plot:
image
So maybe I'm misunderstanding what you mean by an annotation_text or it could be something else causing the bug. Can you please post a MWE or provide details on how you generate the non-displayed annotation-text? Is it a subplotted figure object or non-subplotted figure object? Is the annotation text supposed to be on an hline,hrect,layout_image,etc.? I'm happy to investigate but just can't seem to reproduce it.
yes of course, my problem looks like this:
import plotly
import plotly.graph_objects as go
fig = go.Figure()
fig.add_traces(go.Scatter(x=[1,2,3],y=[-0.009,-0.008,-0.01], yaxis='y',name='y1 trace'))
fig.add_traces(go.Scatter(x=[2,3,4],y=[-50,-52,-58], yaxis='y3',name='y3 trace'))
fig.add_hline(y=-58.,
line_color='darkblue',
yref = 'y3',
line_dash='dot',
annotation_text='annotation goes here (y3)',
annotation_position='bottom right'
)
fig.add_hline(y=-52.,
line_color='darkblue',
yref = 'y3',
line_dash='dot',
annotation_text='annotation goes here (y3)',
annotation_position='bottom right'
)
fig.update_layout(
xaxis=dict(
title='some x axis',
domain=[0.04,0.92],
range=['2023-1-1','2024-1-1']),
yaxis=dict(
title='some y axis',
range=[-0.017,-0.0068],
gridcolor='lightgrey'
),
yaxis3=dict(
title='another y axis',
anchor='x',
overlaying='y',
side='right',
tickmode='array',
tickvals=[-52,-55,-58],
range=[-60,-21],
),
)
plotly.offline.plot(fig,filename='plot_temp.html')
If one changes the yaxis range to
range=[-60,-0.0068]
Figure 2023年05月12日 095556
the annotation and another hline appear
sideinfo:
I am running Python 3.10.9
...layed on the primary y instead of the yref supplied with the axis_spanning_shape
...ithub.com/zfoltz/plotly.py into axis_spanning_layout_object_xref_yref_bug
Thanks for pointing this out and the code @endursa! Looks like I've got it figured out. It appears that when using the annotation_text parameter, the add_annotation function is called without passing the supplied yref see https://github.com/plotly/plotly.py/blob/fc3ef002c7a7898b9244b1549757a64e8df266dd/packages/python/plotly/plotly/basedatatypes.py#L4031-4037
So what is happening is the annotation is showing on the primary y and your shape is showing on the yaxis corresponding to the yref given. Interestingly, adding annotation text by passing text values in the label parameter such as:
label={'text':'my custom annotation'}
actually operates differently under the hood and therefore does not result in this bug. Regardless, I added the necessary yref kwarg to the offending function call and now it's working properly.
endursa
commented
May 15, 2023
Thank you very much!
As far as my use case is concerned, it works now as expected :)
Hey @alexcjohnson anything else needed before merge?
Uh oh!
There was an error while loading. Please reload this page.
This PR is related to issue #3755 which, to put more generally, is that shapes and annotations when supplied with a
yrefparameter are automatically drawn on the primary y-axis despite the suppliedyrefvalue. The only way that a shape or annotation can currently be drawn on an axis that differs from the primary axes is when the figure object is created withsubplots.make_subplots()with thespecslist parameter set to'secondary_y':Truefor that specific subplot. In the case of a non-subplotted figure object, it is impossible as the following line:plotly.py/packages/python/plotly/plotly/basedatatypes.py
Line 4051 in 956ab2c
yref = 'y'when there is not more than one subplot. It is also possible to make a figure object with subplot grid of (1,1) when using plotly express. Using that method there is no way to allow thesecondary_y:Trueto the figure object therefore specifyingyrefwill result in the shape or annotation plotting on the primary y axis regarless of the specifiedyrefand if thesecondary_y=Trueparameter is supplied in the method to add the shape or annotation, that will result in the following error:plotly.py/packages/python/plotly/plotly/basedatatypes.py
Lines 1562 to 1567 in 956ab2c
This error is also missing it's
string.format()method and parameters which are fixed in this as well.For subplots that use the
subplots.make_subplots()with thespecslist parameter set to'secondary_y':Truethis change does not cause the loss of any functionality it just extends the ability to draw shapes and annotations on additional y-axes when generating figure objects without thesubplots.make_subplots()method. Specifyingyrefand if thesecondary_yparameters will not result in an error when used with plotly express (a figure object with a (1,1) subplot grid) or a non subplotted figure object (such as when usinggo.Figure()), it will just proceed with applying it to the specifiedyref.Code PR
plotly.graph_objects, my modifications concern thecodegenfiles and not generated files.modified existing tests.
new tutorial notebook (please see the doc checklist as well).