How to plot density of lines with plotly

Question:

Let’s say I have a set lines (y vs. x) that are the result of a random process.

I am looking for a visualization that shows the spread of the lines.

Concretely I am looking to get an e.g. transparency-graded filled region where the opacity corresponds to the height of the histogram at that point.

Somewhat like the plotly “Filled Lines” example, except that I am not looking for hard borders to the area filled but a gradual phasing out using transparency.

One example similar to what I am looking to realize is shown in on this blog:
enter image description here

I would like to plot different sets of lines (e.g. different experimental conditons) on the same plot in different colours to visually compare their results.

Asked By: ARF

||

Answers:

One approach you could use is matplotlib’s LineCollection. You can use cmap and explicitly assign alpha transparency to each line int the collection.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection


N = 100
x = np.arange(N)
# Here are many sets of y to plot vs x
ys = [x**2+ x + i for i in x]

# We need to set the plot limits, they will not autoscale
fig, ax = plt.subplots()
ax.set_xlim(0,20)
ax.set_ylim(0,200)

verts = [np.column_stack([x, y]) for y in ys]

a_first = np.linspace(0,1,50)
alpha_array =np.concatenate((np.flip(a_first),a_first))

line_segments = LineCollection(verts,linewidth=2, cmap="Blues_r", array=alpha_array)
ax.add_collection(line_segments)
fig.colorbar(line_segments)
plt.show()

enter image description here

Answered By: dubbbdan

Since you’re specifically asking for Plotly, one approach could be to visually represent all your results from your random process with an indiviudal line and a certain opacity.

Plot:

enter image description here

Code:

# imports
from plotly.subplots import make_subplots
import plotly.graph_objs as go
import pandas as pd
import numpy as np

# random data
np.random.seed(123)
frame_rows = 50
frame_cols = 500
frame_columns = ['V_'+str(e) for e in list(range(frame_cols+1))]
df=pd.DataFrame()

for col in frame_columns:
    df[col]=np.sin(np.arange(0,frame_rows/10, 0.1)*np.random.uniform(low=0.85, high=0.99))

# plotly figure
fig=go.Figure()
for i in range(1, frame_cols):
        #print(str(i))
        fig.add_trace(go.Scatter(x=df.index,
                                 y=df[df.columns[i]].values,
                                 showlegend=False,           # hides trace name from legend
                                 hoverinfo='skip',           # turns off hoverinfo
                                 name = None,
                                 mode = 'lines',
                                 line_color='black',
                                 opacity = 0.008
                                )
                     )

# add mean of all rows to the plot
df_mean=df.mean(axis=1).to_frame()
df_mean.columns=['mean']
# show mean
fig.add_trace(go.Scatter(x=df_mean.index, y=df_mean['mean'].values,
                          name='mean lines',
                          line_color='red',
                          line=dict(width=2),
                          mode='lines')
             )
        
fig.show()
Answered By: vestland
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.