Someone looking at this graph can wonder why are you comparing values of different ranges. You can get the right information setting the same range for both yaxis and yaxis2:
My intention is to do cointegration analysis between time series, many of them often donโt come in the same scale (EG: labor hours, value-added, log-scaled, nominal scaled). So having a way to highlight the spread seems useful.
Unfortunately, your suggestion doesnโt seem to help the problem. As soon as I scale the numbers for a certain Ydata, all y-axis ends up scaling accordingly.
import plotly.graph_objects as go
from plotly.subplots import make_subplots
fig = make_subplots(specs=[[{"secondary_y": True}]])
y1 = [3, 4, 8, 3]
y2= [1, 6, 2, 6]
fig.add_trace(go.Scatter(
x=[1, 2, 3, 4],
y=y1,
fill=None,
name= 'Y1 line',
mode='lines',
line_color='blue' ), secondary_y=False)
fig.add_trace(go.Scatter(
x=[1, 2, 3, 4],
y=[1, 6, 2, 6],
name= 'Y2 line',
fill='tonexty', # fill area between trace0 and trace1
mode='lines',
line_color='red'), secondary_y=False)
fig.add_trace(go.Scatter(
x=[1, 2, 3, 4],
y=[1, 6, 2, 6],
showlegend=False,
mode='markers', marker_size=0.1,
line_color='red'), secondary_y=True)
fig.update_layout(
xaxis_domain=[0.15, 0.9],
yaxis=dict(
title="Y1",
titlefont_color="#1f77b4",
tickfont_color="#1f77b4"
),
yaxis2=dict(
title="Y2",
titlefont_color="red",
tickfont_color="red",
))
fig.show()
import plotly.graph_objects as go
from plotly.subplots import make_subplots
fig = make_subplots(specs=[[{"secondary_y": True}]])
y1 = [3, 4, 8, 3]
y2= [1, 6, 2, 6]
fig.add_trace(go.Scatter(
x=[1, 2, 3, 4],
y=y1,
fill=None,
name= 'Y1 line',
mode='lines',
line_color='blue' ), secondary_y=False)
fig.add_trace(go.Scatter(
x=[1, 2, 3, 4],
y=[10, 60, 20, 60],
name= 'Y2 line',
fill='tonexty', # fill area between trace0 and trace1
mode='lines',
line_color='red'), secondary_y=False)
fig.add_trace(go.Scatter(
x=[1, 2, 3, 4],
y=[10, 60, 20, 60],
showlegend=False,
mode='markers', marker_size=0.1,
line_color='red'), secondary_y=True)
fig.update_layout(
xaxis_domain=[0.15, 0.9],
yaxis=dict(
title="Y1",
titlefont_color="#1f77b4",
tickfont_color="#1f77b4"
),
yaxis2=dict(
title="Y2",
titlefont_color="red",
tickfont_color="red",
))
fig.show()
So Y1 in this case is plotted against the Y2-axis, bringing me back to my original problem. Ideally, Y1 axis should be 1-8, while Y2 axis should be 10-60. Changing the parameters of secondary_y=
from False
to True
brings me back to my original problem.
The solution Iโm trying to get is for Y1 and Y2 to be plot in independent-axis (which plotly already has a solution for), and to have the tonexty
function to work for Y-lines that occur in different Y-axis scales.
Alternatively, I can just try to scale all different Ydata values to fit in the same Y-axis. Not sure if it would cause problems for research interpretation.
Original
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Scatter(
x= df.Year,
y= df['Value added'],
name = 'Value added',
yaxis= 'y1',
mode= 'lines',
fill= None,
))
fig.add_trace(go.Scatter(
x= df.Year[1:],
y= df['Wages paid'],
name = 'Wages paid',
yaxis= 'y2',
mode= 'lines',
fill= None,
))
fig.add_trace(go.Scatter(
x= df.Year,
y= df['Total workers by year end'],
name = 'Total workers by year end',
yaxis= 'y3',
mode= 'lines',
fill='tonexty',
))
###############
fig.update_layout(
xaxis=dict(
domain=[0.15, 0.9]
),
yaxis=dict(
title="Value added ($)",
titlefont=dict(
color="#1f77b4"
),
tickfont=dict(
color="#1f77b4"
)
),
yaxis2=dict(
title="Wages paid ($)",
titlefont=dict(
color="red"
),
tickfont=dict(
color="red"
),
anchor="free",
overlaying="y",
side="left",
position = 0.0
),
yaxis3=dict(
title="Total workers by year end",
titlefont=dict(
color="green"
),
tickfont=dict(
color="green"
),
anchor="x",
overlaying="y",
side="right",
),
height= 600,
width= 900,
title= "Value Spread (1963-2019)"
)
fig.show()
Work around (using a rescaled data set, also the chart I wanted)
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Scatter(
x= a.Year,
y= a['Value added'],
name = 'Value added',
yaxis= 'y1',
mode= 'lines',
fill= None,
))
fig.add_trace(go.Scatter(
x= a.Year,
y= a['Wages paid'],
name = 'Wages paid',
yaxis= 'y1',
mode= 'lines',
fill= 'tonexty',
))
fig.add_trace(go.Scatter(
x= a.Year,
y= a['Total workers by year end'],
name = 'Total workers by year end',
yaxis= 'y1',
mode= 'lines',
fill='tonexty',
))
###############
fig.update_layout(
xaxis=dict(
domain=[0.15, 0.9]
),
yaxis=dict(
title="Scaled values",
titlefont=dict(
color="#1f77b4"
),
tickfont=dict(
color="#1f77b4"
)
),
height= 600,
width= 900,
title= "Value Spread, (1963-2019)"
)
fig.show()
However, this method loses the clarity at communicating the true scale for each variable. But thanks for the help and ideas anyway.