Skip to content
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

[BUG] Legend does not display when trace has no real data points #293

Open
mhangaard opened this issue Feb 5, 2024 · 4 comments
Open

[BUG] Legend does not display when trace has no real data points #293

mhangaard opened this issue Feb 5, 2024 · 4 comments
Assignees
Labels
bug Something isn't working

Comments

@mhangaard
Copy link

mhangaard commented Feb 5, 2024

Describe the bug 🖍️
When plotting a trace with empty x and y, the legend does not display. Plotly has limited options for customizing the legend, so an empty trace is useful in combination with legendgroup to customize the legend.
newplot (31)

Reproducing the bug 🔍

import numpy as np
import pandas as pd
import plotly.graph_objects as go
from plotly_resampler import register_plotly_resampler, unregister_plotly_resampler

# comment out this line to get native plotly behavior
register_plotly_resampler(mode="auto", default_n_shown_samples=100)

n = 10000
x = np.arange(n)
x_time = pd.date_range("2020-01-01", freq="1s", periods=len(x))
noisy_sine = (3 + np.sin(x / 2000) + np.random.randn(n) / 10) * x / (n / 4)

fig = go.Figure()
fig.add_trace(go.Scattergl(x=[None], y=[None], name="yp2", showlegend=True, legendgroup="yp2"))
fig.add_trace(go.Scattergl(y=noisy_sine + 2, name="yp2", showlegend=False, legendgroup="yp2"))
fig.add_trace(go.Scattergl(y=noisy_sine - 3, name="ym1"))
fig

Expected behavior 🔧
Native plotly behavior is that the legend of the empty trace appears (blue "yp2" on this screenshot). I can rely on the legend group to toggle the red trace by clicking the "yp2" legend.
newplot (32)

I would probably not be able to get the prefixing and suffixing, on the other trace in same legendgroup, but that's also ok.

Environment information:

  • OS: Ubuntu @ WSL2
  • Python environment:
    • Python version: 3.11
    • plotly-resampler environment:
      • Jupyter-lab 4.1.0
      • ipywidgets 8.1.1
  • plotly-resampler version: 0.9.2

Additional context
I have the same behavior in a Dash app.

@mhangaard mhangaard added the bug Something isn't working label Feb 5, 2024
@jonasvdd
Copy link
Member

Hi @mhangaard,

Thank you for providing such a detailed report. 👏🏼

I believe your issue is caused by the check_nans argument of plotly-resampler. The tsdownsample aggregators were (until recently - see this PR 🚧 ) not able to handle NaN-float values, as such. We remove NaN from the input traces fed to plotly-resampler. However, as .isna can be time-consuming when adding a lot of traces, we introduced the check_nans property, so that users can control this NaN checking operation when they are certain no NaNs occur.

Given that your "empty" trace is not a large trace, NaNs should actually not be removed and your described use case is indeed a bug!
But given the PR in progress, this will not be fixed, as this will not occur any more, given that NaN handling will now be performed at data-aggregation runtime (and this will never occur for small empty traces).

TLDR: workaround

use the check_nans argument in the add_trace method in plotly-resampler=0.9.2, your described issue should be fixed in plotly-resampler>0.9.2 .

Working example ⬇️ :

import numpy as np
import pandas as pd
import plotly.graph_objects as go
from plotly_resampler import register_plotly_resampler, unregister_plotly_resampler

# comment out this line to get native plotly behavior
register_plotly_resampler(mode="auto", default_n_shown_samples=100)

n = 10000
x = np.arange(n)
x_time = pd.date_range("2020-01-01", freq="1s", periods=len(x))
noisy_sine = (3 + np.sin(x / 2000) + np.random.randn(n) / 10) * x / (n / 4)
fig = go.Figure()

fig.add_trace(
    go.Scattergl(x=[None], y=[None], name="yp2", showlegend=True, legendgroup="yp2"),
    # NOTE: I added this argument (this is not that loosely coupled, but it works for plotly-resampler=0.9.2)
    check_nans=False,
)
fig.add_trace(
    go.Scattergl(y=noisy_sine + 2, name="yp2", showlegend=False, legendgroup="yp2")
)
fig.add_trace(go.Scattergl(y=noisy_sine - 3, name="ym1"))
fig

image

Kind regards,
Jonas

@jonasvdd jonasvdd self-assigned this Mar 11, 2024
@jonasvdd
Copy link
Member

related: #294

@mhangaard
Copy link
Author

It can be argued that Plotly should have more options to customize the legend items, instead of having to hack the legend using an empty trace.

@mhangaard
Copy link
Author

fig.add_trace with check_nans=False made it work for me. Thank you @jonasvdd!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants