fishbacp
fishbacp

Reputation: 1263

Plotly Express: Plotting individual columns of a dataframe as multiple plots (scrollable) using plotly express

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.

Upvotes: 0

Views: 597

Answers (1)

r-beginners
r-beginners

Reputation: 35230

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

Upvotes: 2

Related Questions