Python Plotly Subplots with an x shared axis and multiple y axis

I would like to know if it is possible to create subplots with Plotly with an x shared axis and multiple y axis. This what I want to do: where '##' means the plot

[y2, y1, ##, y3]
[y5, y4, ##, y6]
[    y7, ##    ]
[    y8, ##, y9]
[    y10, ##, y11]
[    y12, ##    ]
[         x     ]

This is my code: I am using make_subplots with 6 rows and 1 col, then I definded 12 y axes with their relative position and I added 5 more x axis only to use anchor on my different y axes.

def plot_xshared(dfs):
df_flow_tmp, df_watlow, df_pico, df_flow, df_UV, df_UV_RMS, df_UV_hide, df_P, df_IR, df_IR_RMS, df_IR_hide, df_Pd, df_nearfield, df_farfield = dfs

w, yd = xyaxes_dom_yaxes_pos(gap=0, rows=6)

color_UV=['#19D3F3']
color_UV_RMS=['#636EFA']
color_UV_hide=['brown', 'black', 'blue']
color_P=['#AB63FA']

color_IR=['#EF553B']
color_RMS=['#FFA15A']
color_IR_hide=['brown', 'black', 'blue']
color_Pd=['#636EFA']

color_Position=['blue', 'red']
color_width=['blue', 'red']

fig = make_subplots(rows=6, cols=1,
                    shared_xaxes=True
                   )


fig.update_layout(showlegend=True,
                  legend=dict(groupclick='toggleitem'),
                  legend_title_text='Legend',
                  xaxis1=dict(anchor='y1',
                              domain=[w[1],w[-2]]
                             ), #common x shared axis
                  yaxis1=dict(title='Energy (mJ)',
                              anchor='x1',
                              overlaying='y1',
                              side='left',
                              domain=yd[0]
                             ), #UV
                  yaxis2=dict(title='RMS ()',
                              anchor='free',
                              overlaying='y1',
                              side='left',
                              position=w[0]
                             ), #UV
                  yaxis3=dict(title='Power (W)',
                              anchor='x1',
                              overlaying='y1',
                              side='right'
                             ), #UV
                  xaxis2=dict(anchor='y4',
                              domain=[w[1],w[-2]]
                             ),
                  yaxis4=dict(title='Energy (mJ)',
                              anchor='x2',
                              overlaying='y4',
                              side='left',
                              domain=yd[1]
                             ), #IR
                  yaxis5=dict(title='RMS ()',
                              anchor='free',
                              overlaying='y4',
                              side='left',
                              position=w[0]
                             ), #IR
                  yaxis6=dict(title='Power (W)',
                              anchor='x2',
                              overlaying='y4',
                              side='right'
                             ), #IR
                  xaxis3=dict(anchor='y7',
                              domain=[w[1],w[-2]]
                             ),
                  yaxis7=dict(title='Temperature (°C)',
                              anchor='x3',
                              overlaying='y7',
                              side='left',
                              domain=yd[2]
                             ), #temperature
                  xaxis4=dict(anchor='y8',
                              domain=[w[1],w[-2]]
                             ),
                  yaxis8=dict(title='Position ()',
                              anchor='x4',
                              overlaying='y8',
                              side='left',
                              domain=yd[3]
                             ), #far field
                  yaxis9=dict(title='Width ()',
                              anchor='x4',
                              overlaying='y8',
                              side='right'
                             ), #far field
                  xaxis5=dict(anchor='y10',
                              domain=[w[1],w[-2]]
                             ),
                  yaxis10=dict(title='Position ()',
                              anchor='x5',
                              overlaying='y10',
                              side='left',
                              domain=yd[4]
                             ), #near field
                  yaxis11=dict(title='Width ()',
                               anchor='x5',
                               overlaying='y10',
                               side='right'
                              ), #near field
                  xaxis6=dict(anchor='y12',
                              domain=[w[1],w[-2]]
                             ),
                  yaxis12=dict(title='Flow ()',
                               anchor='x6',
                               overlaying='y12',
                               side='left',
                               domain=yd[5]
                              ) #flow
                 )

### UV ###
#Energy
for i in range(len(df_UV.columns)):
    fig.add_trace(go.Scatter(x=df_UV.index,
                             y=df_UV[df_UV.columns[i]],
                             name=('%s' %(df_UV.columns[i])),
                             xaxis='x1',
                             yaxis='y1',
                             line=dict(color=color_UV[i]),
                             legendgroup='UV',
                             legendgrouptitle_text='UV'
                            ),
                  row=1,
                  col=1
                 )

#RMS
fig.add_trace(go.Scatter(x=df_UV_RMS.index,
                         y=df_UV_RMS[df_UV_RMS.columns[0]],
                         name=('%s' %(df_UV_RMS.columns[i])),
                         xaxis='x1',
                         yaxis='y2',
                         line=dict(color=color_UV_RMS[i]),
                         legendgroup='UV',
                         legendgrouptitle_text='UV'
                        ),
              row=1,
              col=1
             )

#Mean, Max, Min
for i in range(len(df_UV_hide.columns)):
    fig.add_trace(go.Scatter(x=df_UV_hide.index,
                             y=df_UV_hide[df_UV_hide.columns[i]],
                             name=('%s' %(df_UV_hide.columns[i])),
                             xaxis='x1',
                             yaxis='y1',
                             line=dict(color=color_UV_hide[i]),
                             visible='legendonly',
                             legendgroup='UV',
                             legendgrouptitle_text='UV'
                            ),
                  row=1,
                  col=1
                 )

#Power
for i in range(len(df_P.columns)):
    fig.add_trace(go.Scatter(x=df_P.index,
                             y=df_P[df_P.columns[i]],
                             name=('%s' %(df_P.columns[i])),
                             xaxis='x1',
                             yaxis='y3',
                             line=dict(color=color_P[i]),
                             legendgroup='UV',
                             legendgrouptitle_text='UV'
                            ),
                  row=1,
                  col=1
                 )

### IR ###
#Energy
for i in range(len(df_IR.columns)):
    fig.add_trace(go.Scatter(x=df_IR.index,
                             y=df_IR[df_IR.columns[i]],
                             name=('%s' %(df_IR.columns[i])),
                             xaxis='x2',
                             yaxis='y4',
                             line=dict(color=color_IR[i]),
                             legendgroup='IR',
                             legendgrouptitle_text='IR'
                            ),
                  row=2,
                  col=1
                 )

#RMS
fig.add_trace(go.Scatter(x=df_IR_RMS.index,
                         y=df_IR_RMS[df_IR_RMS.columns[0]],
                         name='IR RMS',
                         xaxis='x2',
                         yaxis='y5',
                         line=dict(color=color_RMS[0]),
                         legendgroup='IR',
                         legendgrouptitle_text='IR'
                        ),
              row=2,
              col=1
             )

#Mean, Max, Min
for i in range(len(df_IR_hide.columns)):
    fig.add_trace(go.Scatter(x=df_IR_hide.index,
                             y=df_IR_hide[df_IR_hide.columns[i]],
                             name=('%s' %(df_IR_hide.columns[i])),
                             xaxis='x2',
                             yaxis='y4',
                             line=dict(color=color_IR_hide[i]),
                             visible='legendonly',
                             legendgroup='IR',
                             legendgrouptitle_text='IR'
                            ),
                  row=2,
                  col=1
                 )

#Depolar power
for i in range(len(df_Pd.columns)):
    fig.add_trace(go.Scatter(x=df_Pd.index,
                             y=df_Pd[df_Pd.columns[i]],
                             name=('%s' %(df_Pd.columns[i])),
                             xaxis='x2',
                             yaxis='y6',
                             line=dict(color=color_Pd[i]),
                             legendgroup='IR',
                             legendgrouptitle_text='IR'
                            ),
                  row=2,
                  col=1
                 )
    
### TEMPERATURE ###
#Flowmeter
for i in range(len(df_flow_tmp.columns)):
    fig.add_trace(go.Scatter(x=df_flow_tmp.index,
                             y=df_flow_tmp[df_flow_tmp.columns[i]],
                             name=('%s' %(df_flow_tmp.columns[i])),
                             xaxis='x3',
                             yaxis='y7',
                             legendgroup='Temperature',
                             legendgrouptitle_text='Temperature'
                            ),
                  row=3,
                  col=1
                 )

#Watlow
for i in range(len(df_watlow.columns)):
    fig.add_trace(go.Scatter(x=df_watlow.index,
                             y=df_watlow[df_watlow.columns[i]],
                             name=('%s' %(df_watlow.columns[i])),
                             xaxis='x3',
                             yaxis='y7',
                             legendgroup='Temperature',
                             legendgrouptitle_text='Temperature'
                            ),
                  row=3,
                  col=1
                 )

#Picolog
for i in range(len(df_pico.columns)):
    fig.add_trace(go.Scatter(x=df_pico.index,
                             y=df_pico[df_pico.columns[i]],
                             name=('%s' %(df_pico.columns[i])),
                             xaxis='x3',
                             yaxis='y7',
                             legendgroup='Temperature',
                             legendgrouptitle_text='Temperature'
                            ),
                  row=3,
                  col=1
                 )

### FAR FIELD ###
#Position x
fig.add_trace(go.Scatter(x=df_farfield.index, 
                         y=df_farfield['Position x'], 
                         name='Position x - Far Field',
                         xaxis='x4',
                         yaxis='y8',
                         line=dict(color=color_Position[0]),
                         legendgroup='Far Field',
                         legendgrouptitle_text='Far Field',
                        ),
              row=4,
              col=1
             )

#Position y
fig.add_trace(go.Scatter(x=df_farfield.index, 
                         y=df_farfield['Position y'], 
                         name='Position y - Far Field',
                         xaxis='x4',
                         yaxis='y8',
                         line=dict(color=color_Position[1]),
                         legendgroup='Far Field',
                         legendgrouptitle_text='Far Field',
                        ),
              row=4,
              col=1
             )

#Width x
fig.add_trace(go.Scatter(x=df_farfield.index, 
                         y=df_farfield['1/e2 X width'], 
                         name='1/e2 x - Far Field',
                         xaxis='x4',
                         yaxis='y9',
                         line=dict(color=color_width[0]),
                         legendgroup='Far Field',
                         legendgrouptitle_text='Far Field',
                        ),
              row=4,
              col=1
             )

#Width y
fig.add_trace(go.Scatter(x=df_farfield.index, 
                         y=df_farfield['1/e2 Y width'], 
                         name='1/e2 y - Far Field',
                         xaxis='x4',
                         yaxis='y9',
                         line=dict(color=color_width[1]),
                         legendgroup='Far Field',
                         legendgrouptitle_text='Far Field',
                        ),
              row=4,
              col=1
             ) 

### NEAR FIELD ###
#Position x
fig.add_trace(go.Scatter(x=df_nearfield.index, 
                         y=df_nearfield['Position x'], 
                         name='Position x - Near Field',
                         xaxis='x5',
                         yaxis='y10',
                         line=dict(color=color_Position[0]),
                         legendgroup='Near Field',
                         legendgrouptitle_text='Near Field',
                        ),
              row=5,
              col=1
             )

#Position y
fig.add_trace(go.Scatter(x=df_nearfield.index, 
                         y=df_nearfield['Position y'], 
                         name='Position y - Near Field',
                         xaxis='x5',
                         yaxis='y10',
                         line=dict(color=color_Position[1]),
                         legendgroup='Near Field',
                         legendgrouptitle_text='Near Field',
                        ),
              row=5,
              col=1
             )

#Width x
fig.add_trace(go.Scatter(x=df_nearfield.index, 
                         y=df_nearfield['1/e2 X width'], 
                         name='1/e2 x - Near Field',
                         xaxis='x5',
                         yaxis='y11',
                         line=dict(color=color_width[0]),
                         legendgroup='Near Field',
                         legendgrouptitle_text='Near Field',
                        ),
              row=5,
              col=1
             )

#Width y
fig.add_trace(go.Scatter(x=df_nearfield.index, 
                         y=df_nearfield['1/e2 Y width'], 
                         name='1/e2 y - Near Field',
                         xaxis='x5',
                         yaxis='y11',
                         line=dict(color=color_width[1]),
                         legendgroup='Near Field',
                         legendgrouptitle_text='Near Field',
                        ),
              row=5,
              col=1
             )

### FLOW ###
for i in range(len(df_flow.columns)):
    fig.add_trace(go.Scatter(x=df_flow.index,
                             y=df_flow[df_flow.columns[i]],
                             name=('%s' %(df_flow.columns[i])),
                             xaxis='x6',
                             yaxis='y12',
                             legendgroup='Flow',
                             legendgrouptitle_text='Flow'
                            ),
                  row=6,
                  col=1
                 )
    
fig.show()

return 1

And this my code to calculate the position:

    #function that returns default yaxis domain for each subplot and the additional yaxes positions
def xyaxes_dom_yaxes_pos(gap, rows):
    if rows < 2:
        raise ValueError('This function works for subplots with  rows>2 and cols=1')
    h_window=  (1-gap)/rows  #window height
    d = 3/10/2
    #xaxis{k} has the domain [w[2],w[-3]] k=1,...rows
    #w[1], w[-2] give the left, resp right yaxes position associated to the default yaxis of the plot window
    yd = []
    for k in range(rows):
        start = k*(h_window+gap)
        end = start+h_window
        yd.append([start, end])
    w  =  [0, d, 2*d, 1-2*d, 1-d, 1]
   
    return w, yd[::-1]  #yd[::-1] contains the domains of the default yaxes 

Finally, I got this:

Subplot image

Thank you for your advice and help.

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum