6

I need to plot a very large number of segments with plotly. Contrary to a regular scatter plot where all points can be connected, here I need to only connect points two by two.

I considered different options:

  • adding line shapes to the plot; apparently relatively slow
  • creating a large number of line plots with only two points

Would there be a more suitable method? Possibly a single scatter plot where only every other couple of points are connected.

I'm looking for an efficient way to produce the plot in Python but also for good rendering performances.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Cedric H.
  • 7,980
  • 10
  • 55
  • 82

1 Answers1

3

This answer builds on the suggestion in the comment from Maximilian Peters, as well as Jezraels approach to insert a new row after every nth row.

A key part is also to include fig.update_traces(connectgaps=False)

Plot:

enter image description here

Complete code:

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

# dataframe, sample
np.random.seed(123)
cols = ['a','b','c', 'd', 'e', 'f', 'g']
X = np.random.randn(50,len(cols))  
df=pd.DataFrame(X, columns=cols)
df=df.cumsum()
df['id']=df.index

# dataframe with every nth row containing np.nan
df2 = (df.iloc[1::2]
         .assign(id = lambda x: x['id'] + 1, c = np.nan)
         .rename(lambda x: x + .5))
df1 = pd.concat([df, df2], sort=False).sort_index().reset_index(drop=True)
df1.loc[df1.isnull().any(axis=1), :] = np.nan
df1


# plotly figure
colors = px.colors.qualitative.Plotly
fig = go.Figure()

for i, col in enumerate(df1.columns[:-1]):
    fig.add_traces(go.Scatter(x=df1.index, y=df1[col],
                              mode='lines+markers', line=dict(color=colors[i])))

fig.update_traces(connectgaps=False)

fig.show()
vestland
  • 55,229
  • 37
  • 187
  • 305