Skip to content

px.bar: when base is used, hoverlabel label should be "base+y: %y" #2786

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

Closed
eddy-geek opened this issue Sep 22, 2020 · 8 comments
Closed

px.bar: when base is used, hoverlabel label should be "base+y: %y" #2786

eddy-geek opened this issue Sep 22, 2020 · 8 comments
Milestone

Comments

@eddy-geek
Copy link
Contributor

Minimal example:

tasks = pd.DataFrame([
    dict(Task="A", Start=0, Elapsed=10),
    dict(Task="B", Start=0, Elapsed=5),
    dict(Task="C", Start=5, Elapsed=10)
])
px.bar(tasks, base='Start', y='Elapsed', text='Task',)

image

Imagine an horizontal gantt-chart where x=Elapsed is Task duration in days. The issue is that Task C has "Elapsed=15" instead of "Elapsed=10".

This also an issue in the graph_objects API in the default hover, but at least adding x as text shows the proper one.

go.Figure(data=[go.Bar(base=tasks['Start'], y=tasks['Elapsed'], text=tasks['Elapsed'])])

image

Note: In px.timeline it's fine since user must give Finish=but in px.bar it's looks pretty misleading to "change" x into finish :-)

If my Task lasts 10 days, the fact that it ends at day 15 is an internal positioning detail.

@nicolaskruchten is it just an oversight from #2585 or do you intend it this way?

@eddy-geek
Copy link
Contributor Author

I just noticed the following:

If I add x as explicit hover_data, it changes the hover data to the correct one:

px.bar(tasks, base='Start', y='Elapsed', text='Task',) # left
px.bar(tasks, base='Start', y='Elapsed', text='Task', hover_data=['Elapsed']) # right

image image

Maybe the second behaviour can be made default?

@nicolaskruchten
Copy link
Contributor

nicolaskruchten commented Sep 24, 2020

This behaviour (at the Plotly.js level) is intentional: when orientation is its default "v", the value shown in the hover label for the "y" value is the y-position of the top of the bar, which is sum of what is provided as base and y. I agree this is confusing when you are passing a value into y which has the semantics of "elapsed", but changing this (in Plotly.js) would be a backwards-incompatible change, so not something we can envision in the short term. This is also basically why we built px.timeline(), with explicit start/end arguments. Adding in automatic "elapsed" computation in PX would be an easy way forward here perhaps?

When you pass in text in go.Bar or hover_data in px.bar, you're effectively overwriting the hover label, so there is a workaround, thankfully.

@nicolaskruchten
Copy link
Contributor

nicolaskruchten commented Sep 24, 2020

That said, maybe PX could should really format its hoverlabel here more clearly to say "start+elapsed: 15" to make this more explicit/less misleading

@nicolaskruchten nicolaskruchten changed the title px: bar base should not change x px.bar: when base is used, hoverlabel label should be "base+y: %y" Sep 24, 2020
@eddy-geek
Copy link
Contributor Author

I agree with not changing plotly.js, this is only about px.bar

Adding in automatic "elapsed" computation in PX would be an easy way forward here perhaps?
PX should really format its hoverlabel here more clearly to say "start+elapsed: 15"

This is good enough since it prevents confusion and makes it more obvious than adding hover_data=['Elapsed'] will work as expected. Still, I wonder why not make it the default behaviour of px.bar(base).

@nicolaskruchten
Copy link
Contributor

Still, I wonder why not make it the default behaviour of px.bar(base)

That's a good idea but the implementation under the hood is a bit more complicated :)

@nicolaskruchten nicolaskruchten added this to the v4.x milestone Sep 24, 2020
@Lxstr
Copy link

Lxstr commented Nov 29, 2022

@nicolaskruchten I have been trying to pass in text to go.bar to avoid the effects of setting a base on an offset stacked bar chart but with no luck.

            name="On Order",
            y = availability_df["Product"],
            x = availability_df["OnOrder"],
            base = on_order_base,
            text = availability_df["OnOrder"],

or

hoverinfo="text",
hovertext = availability_df["OnOrder"],

Is there anything I'm missing? Cheers

@Lxstr
Copy link

Lxstr commented Nov 29, 2022

So the required code in the end works but removes all label text on the actual bars 😞 Is there any way to keep the labels on the bars?

hoverinfo="text",
hovertext = [f'In stock: {val}' for val in availability_df["InStock"]],

I also had to remove this line
fig.update_traces(hovertemplate="%{x}")

I also wonder is this the most effective and CPU efficient way to do it? I feel like these lines to replicate what could be default seems unusual?

Ref: https://dev.to/fronkan/stacked-and-grouped-bar-charts-using-plotly-python-a4p

@gvwilson
Copy link
Contributor

gvwilson commented Jul 5, 2024

Hi - we are trying to tidy up the stale issues and PRs in Plotly's public repositories so that we can focus on things that are still important to our community. Since this one has been sitting for a while, I'm going to close it; if it is still a concern, please add a comment letting us know what recent version of our software you've checked it with so that I can reopen it and add it to our backlog. Alternatively, if it's a request for tech support, please post in our community forum. Thank you - @gvwilson

@gvwilson gvwilson closed this as completed Jul 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants