Please help me with this code!

Hello everyone, this code is driving me insane and I dont even know if it is possible in the first place. To keep it short I have a group of suplots, 5 rows by 1 column, in each row I plotted a couple of curves but in the first row I would like to plot 3 curves, one in the main y axis, one in the secundary axis and the third one in an additional secundary axis but for the love of god I can’t. Any help is welcome. heres the code:

# Crea una figura con subplots
num_rows = 4

nticks=5

#fig = make_subplots(rows=num_rows, cols=1, shared_xaxes=True)
fig = make_subplots(rows=num_rows, cols=1, shared_xaxes=True,
                    specs=[[{"secondary_y": True}] for _ in range(num_rows)], vertical_spacing=0.015)

#---------------------------------------------------------------------------------------------------------------
# Agregar la traza para 'DMEA (m)' en el eje principal
fig.add_trace(go.Scatter(y=df_1['DBTM (m)'], x=df_1.index, name='DBTM (m)', hovertemplate=
                         "<b>DBTM (m)</b><br>" +
                         "Valor: %{y}<br>" +
                         "Profundidad: %{customdata}<br>" +
                         "Fecha: %{x}<extra></extra>",
                         customdata=df_1['DBTM (m)'], line=dict(width=1.5, color='#0000FF')),
                         row=1, col=1, secondary_y=False)

# Agregar la traza para 'BPOS (m)' en el eje secundario
fig.add_trace(go.Scatter(y=df_1['HKLA (ton)'], x=df_1.index, name='HKLA (ton)', hovertemplate=
                         "<b>HKLA (ton)</b><br>" +
                         "Valor: %{y}<br>" +
                         "Profundidad: %{customdata}<br>" +
                         "Fecha: %{x}<extra></extra>",
                         customdata=df_1['DBTM (m)'], line=dict(width=1.5), opacity=1),
                         row=1, col=1, secondary_y=True)

# Actualiza los títulos del eje Y para ambos ejes
fig.update_yaxes(title_text='DBTM (m)', row=1, col=1, secondary_y=False, range=[2500, 7000])
fig.update_yaxes(title_text='HKLA (ton)', row=1, col=1, secondary_y=True)
#---------------------------------------------------------------------------------------------------------------
fig.add_trace(go.Scatter(y=df_1['STKC (spm)'], x=df_1.index, name='STKC (spm)', hovertemplate=
                         f"<b>STKC (spm)</b><br>" +
                         "Valor: %{y}<br>" +
                         "Profundidad: %{customdata}<br>" +
                         "Fecha: %{x}<extra></extra>",
                         customdata=df_1['DBTM (m)'], line=dict(width=1.5)),
                         row=2, col=1)

fig.update_yaxes(title_text='STKC (spm)', row=2, col=1, secondary_y=False, range=[0, 350])
#---------------------------------------------------------------------------------------------------------------
# Agregar la traza para 'BPOS (m)' en el eje secundario
fig.add_trace(go.Scatter(y=df_1['SPPA (psi)'], x=df_1.index, name='SPPA (psi)', hovertemplate=
                         "<b>SPPA (psi)</b><br>" +
                         "Valor: %{y}<br>" +
                         "Profundidad: %{customdata}<br>" +
                         "Fecha: %{x}<extra></extra>",
                         customdata=df_1['DBTM (m)'],line=dict(width=1.5, color='#FABC3F'), opacity=1),
                         row=3, col=1)

# Actualiza los títulos del eje Y para ambos ejes
fig.update_yaxes(title_text='SPPA (psi)', row=3, col=1, secondary_y=False, range=[0, 7000])
#---------------------------------------------------------------------------------------------------------------
fig.add_trace(go.Scatter(y=df_1['TQA (lbs-pie)'], x=df_1.index, name='TQA (lbs-pie)', hovertemplate=
                         f"<b>TQA (lbs-pie)</b><br>" +
                         "Valor: %{y}<br>" +
                         "Profundidad: %{customdata}<br>" +
                         "Fecha: %{x}<extra></extra>",
                         customdata=df_1['DBTM (m)'], line=dict(width=1.5, color='#A020F0')),
                         row=4, col=1, secondary_y=False)

# Agregar la traza para 'BPOS (m)' en el eje secundario
fig.add_trace(go.Scatter(y=df_1['RPMA (rpm)'], x=df_1.index, name='RPMA (rpm)', hovertemplate=
                         "<b>RPMA (rpm)</b><br>" +
                         "Valor: %{y}<br>" +
                         "Profundidad: %{customdata}<br>" +
                         "Fecha: %{x}<extra></extra>",
                         customdata=df_1['DBTM (m)'],line=dict(width=1.5, color='#0BDA51'), opacity=1),
                         row=4, col=1, secondary_y=True)

fig.update_yaxes(title_text='TQA (lbs-pie)', row=4, col=1, secondary_y=False, range=[0, 40000])
fig.update_yaxes(title_text='RPMA (rpm)', row=4, col=1, secondary_y=True, range=[0, 350])
#---------------------------------------------------------------------------------------------------------------
# Agregar la traza para 'RPMA' en un nuevo eje (y3)
fig.add_trace(go.Scatter(y=df_1['MDIA (g/cm3)'], x=df_1.index, name='MDIA (g/cm3)', hovertemplate=
                         "<b>MDIA (g/cm3)</b><br>" +
                         "Valor: %{y}<br>" +
                         "Profundidad: %{customdata}<br>" +
                         "Fecha: %{x}<extra></extra>",
                         customdata=df_1['DBTM (m)'], line=dict(width=1.5), opacity=1, yaxis="y3"),
              row=1, col=1, secondary_y=True)
#---------------------------------------------------------------------------------------------------------------
#este código permite aumentar el tamaño de los labels del eje x
fig.update_xaxes(nticks=20, tickfont=dict(size=14, color='black', family='Arial, bold'))
fig.update_xaxes(showline=True, linewidth=1, linecolor='black')
fig.update_yaxes(showline=True, linewidth=1, linecolor='black')

#este código permite aumentar el tamaño de los labels del eje y
for i in range(1, num_rows + 1):
    fig.update_yaxes(
        tickfont=dict(size=14, color='black', family='Arial, bold'),  # Ajusta el tamaño y el estilo de los ticks
        title_font=dict(size=16, color='black', family='Arial, bold'),  # Ajusta el tamaño y el estilo del título
        row=i, col=1, nticks=5)
#---------------------------------------------------------------------------------------------------------------

# Añade título general y actualiza eje y principal
fig.update_layout(title_text='<br>Parámetros en Tiempo Real Pozo Ixachi-54', height=1000, title_x=0.5, title_y=0.999, legend=dict(
    orientation="h",
    yanchor="bottom",
    y=1.06,
    xanchor="center",
    x=0.5),
    yaxis3=dict(title_text='MDIA (g/cm3)', range=[0, 200], overlaying='y2', side='right', anchor='x', autoshift=True, shift=25)
    )

# Suponiendo que 'fig' es tu figura de Plotly ya configurada
#fig.write_html('./data_output/ixachi_54_time_19082024_22082024.html')

# Muestra el gráfico
fig.show()

Hi @JPcastanoc1 ,

Welcome to the forum!

First, you need to know what exactly the yaxis that used in your subplot.
By printing the fig.data before your last line which is fig.show(), you can identify the yaxis that available for the second right yaxis in your first row.

...

print(fig.data)

# Muestra el gráfico
fig.show()

If you have 5 subplots, it means yaxis, yaxis2... yaxis9, yaxis10 have been reserved for 5 subplots, because by default 1 subplot needs two yaxis (for left and right side).

You can use yaxis11 or above to set the second right yaxis in your first row.
For example the trace that you want to change the yaxis as the second right yaxis in your first row is the 3rd trace.

fig.data[2].yaxis = 'y11'

You also need to decrease the all xaxisdomain to give space for the second right yaxis.

fig.update_layout(
	xaxis=dict(
        domain=[0., 0.75]
    ),
    xaxis2=dict(
        domain=[0., 0.75]
    ),
    xaxis3=dict(
        domain=[0., 0.75]
    ),
    xaxis4=dict(
        domain=[0., 0.75]
    ),
    xaxis5=dict(
        domain=[0., 0.75]
    )
)

The result with simple data will be like image below.

Hope this help.

3 Likes

First of all Faris I would like to thank you from the bottom of my heart, this was the final piece that I needed to complete my plot. Thank you for taking the time to analize it and give me a response. I would like to show you the final plot as well as the final code just for you to have it. As you will see I added a third curve on the third row which gave little trouble because it was plotting itself on the first row but using the logic you showed me, I used fig.layout and understand that I had to overlayed against ‘y5’. Thanks again!.

from plotly.subplots import make_subplots
import plotly.graph_objects as go

# Establecer las fechas de inicio y fin para el filtro
fecha_inicio = df.index[0]
fecha_fin = df.index[-1]

# Filtrar el DataFrame en el rango de fechas
df_1 = df.loc[fecha_inicio:fecha_fin]

# Crea una figura con subplots
num_rows = 4

#fig = make_subplots(rows=num_rows, cols=1, shared_xaxes=True)
fig = make_subplots(rows=num_rows, cols=1, shared_xaxes=True,
                    specs=[[{"secondary_y": True}] for _ in range(num_rows)], vertical_spacing=0.015)

#---------------------------------------------------------------------------------------------------------------
# Agregar la traza para 'DMEA (m)' en el eje principal
fig.add_trace(go.Scatter(y=df_1['DBTM (m)'], x=df_1.index, name='DBTM (m)', hovertemplate=
                         "<b>DBTM (m)</b><br>" +
                         "Valor: %{y}<br>" +
                         "Profundidad: %{customdata}<br>" +
                         "Fecha: %{x}<extra></extra>",
                         customdata=df_1['DBTM (m)'], line=dict(width=1.5, color='#0000FF')),
                         row=1, col=1, secondary_y=False)

# Agregar la traza para 'BPOS (m)' en el eje secundario
fig.add_trace(go.Scatter(y=df_1['HKLA (ton)'], x=df_1.index, name='HKLA (ton)', hovertemplate=
                         "<b>HKLA (ton)</b><br>" +
                         "Valor: %{y}<br>" +
                         "Profundidad: %{customdata}<br>" +
                         "Fecha: %{x}<extra></extra>",
                         customdata=df_1['DBTM (m)'], line=dict(width=1.5), opacity=1),
                         row=1, col=1, secondary_y=True)

# Actualiza los títulos del eje Y para ambos ejes
fig.update_yaxes(title_text='DBTM (m)', row=1, col=1, secondary_y=False, range=[2500, 7000])
fig.update_yaxes(title_text='HKLA (ton)', row=1, col=1, secondary_y=True)

# Agregar la traza para 'RPMA' en un nuevo eje (y3)
fig.add_trace(go.Scatter(y=df_1['MDIA (g/cm3)'], x=df_1.index, name='MDIA (g/cm3)', hovertemplate=
                         "<b>MDIA (g/cm3)</b><br>" +
                         "Valor: %{y}<br>" +
                         "Profundidad: %{customdata}<br>" +
                         "Fecha: %{x}<extra></extra>",
                         customdata=df_1['DBTM (m)'], line=dict(width=1.5), opacity=1),
                         row=1, col=1, secondary_y=True)
#---------------------------------------------------------------------------------------------------------------
fig.add_trace(go.Scatter(y=df_1['STKC (spm)'], x=df_1.index, name='STKC (spm)', hovertemplate=
                         f"<b>STKC (spm)</b><br>" +
                         "Valor: %{y}<br>" +
                         "Profundidad: %{customdata}<br>" +
                         "Fecha: %{x}<extra></extra>",
                         customdata=df_1['DBTM (m)'], line=dict(width=1.5)),
                         row=2, col=1)

fig.update_yaxes(title_text='STKC (spm)', row=2, col=1, secondary_y=False, range=[0, 350])
#---------------------------------------------------------------------------------------------------------------
# Agregar la traza para 'BPOS (m)' en el eje secundario
fig.add_trace(go.Scatter(y=df_1['SPPA (psi)'], x=df_1.index, name='SPPA (psi)', hovertemplate=
                         "<b>SPPA (psi)</b><br>" +
                         "Valor: %{y}<br>" +
                         "Profundidad: %{customdata}<br>" +
                         "Fecha: %{x}<extra></extra>",
                         customdata=df_1['DBTM (m)'],line=dict(width=1.5, color='#FABC3F'), opacity=1),
                         row=3, col=1, secondary_y=False)

# Agregar la traza para 'BPOS (m)' en el eje secundario
fig.add_trace(go.Scatter(y=df_1['BPOS (m)'], x=df_1.index, name='BPOS (m)', hovertemplate=
                         "<b>BPOS (m)</b><br>" +
                         "Valor: %{y}<br>" +
                         "Profundidad: %{customdata}<br>" +
                         "Fecha: %{x}<extra></extra>",
                         customdata=df_1['DBTM (m)'], line=dict(width=1.5), opacity=1),
                         row=3, col=1, secondary_y=True)

# Actualiza los títulos del eje Y para ambos ejes
fig.update_yaxes(title_text='SPPA (psi)', row=3, col=1, secondary_y=False, range=[0, 7000])
fig.update_yaxes(title_text='BPOS (m)', row=3, col=1, secondary_y=True)

# Agregar la traza para 'RPMA' en un nuevo eje (y3)
fig.add_trace(go.Scatter(y=df_1['WOBA (ton)'], x=df_1.index, name='WOBA (ton)', hovertemplate=
                         "<b>WOBA (ton)</b><br>" +
                         "Valor: %{y}<br>" +
                         "Profundidad: %{customdata}<br>" +
                         "Fecha: %{x}<extra></extra>",
                         customdata=df_1['DBTM (m)'], line=dict(width=1.5), opacity=1),
                         row=3, col=1, secondary_y=True)
#---------------------------------------------------------------------------------------------------------------
fig.add_trace(go.Scatter(y=df_1['TQA (lbs-pie)'], x=df_1.index, name='TQA (lbs-pie)', hovertemplate=
                         f"<b>TQA (lbs-pie)</b><br>" +
                         "Valor: %{y}<br>" +
                         "Profundidad: %{customdata}<br>" +
                         "Fecha: %{x}<extra></extra>",
                         customdata=df_1['DBTM (m)'], line=dict(width=1.5, color='#A020F0')),
                         row=4, col=1, secondary_y=False)

# Agregar la traza para 'BPOS (m)' en el eje secundario
fig.add_trace(go.Scatter(y=df_1['RPMA (rpm)'], x=df_1.index, name='RPMA (rpm)', hovertemplate=
                         "<b>RPMA (rpm)</b><br>" +
                         "Valor: %{y}<br>" +
                         "Profundidad: %{customdata}<br>" +
                         "Fecha: %{x}<extra></extra>",
                         customdata=df_1['DBTM (m)'],line=dict(width=1.5, color='#0BDA51'), opacity=1),
                         row=4, col=1, secondary_y=True)

fig.update_yaxes(title_text='TQA (lbs-pie)', row=4, col=1, secondary_y=False, range=[0, 40000])
fig.update_yaxes(title_text='RPMA (rpm)',    row=4, col=1, secondary_y=True, range=[0, 350])

#---------------------------------------------------------------------------------------------------------------

fig.update_layout(
	xaxis=dict(
        domain=[0., 0.9]
    ),
    xaxis2=dict(
        domain=[0., 0.9]
    ),
    xaxis3=dict(
        domain=[0., 0.9]
    ),
    xaxis4=dict(
        domain=[0., 0.9]
    ))

# Añade título general y actualiza eje y principal
fig.update_layout(title_text='<br>Parámetros en Tiempo Real Pozo Ixachi-54',
                  height=1000, title_x=0.5, title_y=0.999,
                  legend=dict(orientation="h", yanchor="bottom", y=1.05, xanchor="center", x=0.5))

fig.update_layout(yaxis9=dict(title_text='MDIA (g/cm3)', range=[0, 200], overlaying='y', side='right', anchor='free', autoshift=True, shift=25))
fig.update_layout(yaxis10=dict(title_text='WOBA (ton)', range=[0, 200], overlaying='y5', side='right', anchor='free', autoshift=True, shift=25))

fig.data[2].yaxis = 'y9'
fig.data[6].yaxis = 'y10'

# Muestra el gráfico
fig.show()```
1 Like

Thanks - that explains something that I didn’t understand at all until now :slight_smile: