0

I posed a question at Plotly: How to add a horizontal scrollbar to a plotly express figure? asking how to add a horizontal scrollbar to a plotly express figure for purposes of visualizing a long multivariate time series. A solution for a simple example consisting of three series having 100K points each was given as follows:

import plotly.express as px
import numpy as np
import pandas as pd

np.random.seed(123)
e = np.random.randn(100000,3)
df=pd.DataFrame(e, columns=['a','b','c'])

df['x'] = df.index
df_melt = pd.melt(df, id_vars="x", value_vars=df.columns[:-1])
fig=px.line(df_melt, x="x", y="value",color="variable")

# Add range slider
fig.update_layout(xaxis=dict(rangeslider=dict(visible=True),
                         type="linear"))
fig.show()

This code is nice, but I'd like to have the plots not superimposed on a single set of axes--instead one above the other as would be done with subplot. For example, signal 'a' would appear above signal 'b', which would appear above signal 'c'.

Because my actual time series have at least 50 channels, a vertical scrollbar will likely be necessary.

fishbacp
  • 1,123
  • 3
  • 14
  • 29
  • 1
    Is it not clear to me if you are looking for something like `fig=px.line(df_melt, x="x", y="value",color="variable", facet_row='variable')` or do you want to add a dropdown to pick a given variable. – rpanai Apr 15 '21 at 03:50
  • I wasn't aware of the option facet_row='variable,' which works nicely, but the option of a dropdown sounds great. In fact a checkbox option to select a subset of the signals would be even better. Thoughts on how I could accomplish this? – fishbacp Apr 16 '21 at 12:59
  • If you use dash you can consider a [Multi-Value Dropdown](https://dash.plotly.com/dash-core-components/dropdown) too. – rpanai Apr 16 '21 at 13:04
  • 1
    [Here's](https://stackoverflow.com/questions/65941253/plotly-how-to-toggle-traces-with-a-button-similar-to-clicking-them-in-legend/65962937#65962937) one way you could do it – vestland Apr 16 '21 at 13:19
  • 1
    @vestland nice one! – rpanai Apr 16 '21 at 14:07
  • 1
    @rpanai Thank you! The approach is arguably a bit messy, but it gives you full flexibility with the selection; one, some, all or none. – vestland Apr 16 '21 at 14:29

1 Answers1

2

As far as I know, it may be possible in dash, but it does not exist in plotly. The question you quoted also suggests a range slider as a substitute for the scroll function. At the same time, the range slider is integrated with the graph, so if you don't make the slider function independent, it will disappear on scrolling, which is not a good idea. I think the solution at the moment is to have 50 channels side by side and add a slider.

import plotly.graph_objects as go
import numpy as np
import pandas as pd

np.random.seed(123)
e = np.random.randn(100000,3)
df=pd.DataFrame(e, columns=['a','b','c'])

df['x'] = df.index
df_melt = pd.melt(df, id_vars="x", value_vars=df.columns[:-1])

fig = go.Figure()
fig.add_trace(go.Scatter(x=df_melt.query('variable == "a"')['x'],
                           y=df_melt.query('variable == "a"')['value'], yaxis='y'))

fig.add_trace(go.Scatter(x=df_melt.query('variable == "b"')['x'],
                           y=df_melt.query('variable == "b"')['value'], yaxis='y2'))

fig.add_trace(go.Scatter(x=df_melt.query('variable == "c"')['x'],
                           y=df_melt.query('variable == "c"')['value'], yaxis='y3'))

# Add range slider
fig.update_layout(
    xaxis=dict(
        rangeslider=dict(visible=True),
        type="linear"),
    yaxis=dict(
        anchor='x',
        domain=[0, 0.33],
        linecolor='blue',
        type='linear',
        zeroline=False
    ),
    yaxis2=dict(
        anchor='x',
        domain=[0.33, 0.66],
        linecolor='red',
        type='linear',
        zeroline=False
    ),
    yaxis3=dict(
        anchor='x',
        domain=[0.66, 1.0],
        linecolor='green',
        type='linear',
        zeroline=False
    ),
)

fig.show()

enter image description here

r-beginners
  • 31,170
  • 3
  • 14
  • 32