Show two y axes traces with different scale

I have two traces on my plot, the first trace would be the bar chart, and the second one would be the line on another yaxis, how can I adjust it so that I can see both charts with a slight β€œgap”. This is how my plot looks like when generated:

And this is how I want it to be (adjusted manually) :

Do you know which parameter changes will I need to adjust to get it that way.

Code so far :

fig = px.bar(df, x = "Timestamp", y = 'SUM_kWh', barmode='group')
fig.add_traces(go.Scatter(x= dfx.Timestamp, y=dfx.SUM_kWh, text=dfx.SUM_kWh.apply(lambda val: f"{val/1000:.1f} kW"), textposition= "top center", textfont = {"size" : 8}, mode='lines+markers+text', yaxis="y2", line_shape='spline'))
fig.update_layout(
      yaxis2=dict(
          overlaying="y",
          side="right",
          range=[0, dfx['SUM_kWh'].max() * 0.9],  # Adjust the upper range
          autorangeoptions = dict(
              include = dfx['SUM_kWh'].max() * 1.9,
              maxallowed = dfx['SUM_kWh'].max() * 1.9,
          ),
          showgrid=False,
          zeroline=False,
          title="Total kWh",
          autoshift = True,
          #fixedrange=True
      ),
      yaxis=dict(
          title="SUM_kWh (kW)",  # Set title for the left y-axis
          range=[0, df['SUM_kWh'].max() * 1.2]  # Adjust the range for yaxis
      ),
      autosize=True,  
      legend=dict(
          x=1.05,
          y=0.5,
          traceorder="normal",
  ))

hi @yazouaghe
:wave: Welcome to the community.

Are you able to provide sample data with the code, so we can reproduce the figure locally? This will make it a lot easier to support you.

Here’s a more detailed version of the code with sample data :slight_smile:

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

# Generate random data
n_rows = 90
n_ids = 4

mongo_ids = [f"INV-{i}" for i in range(1, n_ids + 1)]
timestamps = pd.date_range(start="2024-06-10", periods=n_rows, freq="D")
sum_kwh = np.random.uniform(low=10000, high=40000, size=n_rows)

data = {
    'Name': np.random.choice(mongo_ids, size=n_rows),
    'Timestamp': timestamps,
    'SUM_kWh': sum_kwh
}

df = pd.DataFrame(data)
dfx = df[["Timestamp", "SUM_kWh"]].groupby(["Timestamp"]).sum()["SUM_kWh"].reset_index()

fig = px.bar(df, x = "Timestamp", y = 'SUM_kWh', color="Name", barmode='group')
fig.add_traces(go.Scatter(x= dfx.Timestamp, y=dfx.SUM_kWh, mode='lines+markers+text', yaxis="y2", line_shape='spline'))
fig.update_layout(template = "plotly_white", paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)",  showlegend=False,
                    yaxis2=dict(
                        overlaying="y",
                        side="right",
                        range=[0, dfx['SUM_kWh'].max() * 0.9],  # Adjust the upper range
                        autorangeoptions = dict(
                            include = dfx['SUM_kWh'].max() * 1.9,
                            maxallowed = dfx['SUM_kWh'].max() * 1.9,
                        ),
                        showgrid=False,
                        zeroline=False,
                        title="Total kWh",
                        autoshift = True,
                        #fixedrange=True
                    ),
                    yaxis=dict(
                        title="SUM_kWh (kW)",  # Set title for the left y-axis
                        range=[0, df['SUM_kWh'].max() * 1.2]  # Adjust the range for yaxis
                    ),
                    autosize=True,  
                    legend=dict(
                        x=1.05,
                        y=0.5,
                        traceorder="normal",
                ))

fig.update_yaxes(title_text="kWh", secondary_y=False)

Thanks for sharing the code, @yazouaghe .

Would it be something like this?

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

# Generate random data
n_rows = 90
n_ids = 4

mongo_ids = [f"INV-{i}" for i in range(1, n_ids + 1)]
timestamps = pd.date_range(start="2024-06-10", periods=n_rows, freq="D")
sum_kwh = np.random.uniform(low=10000, high=40000, size=n_rows)

data = {
    'Name': np.random.choice(mongo_ids, size=n_rows),
    'Timestamp': timestamps,
    'SUM_kWh': sum_kwh
}

df = pd.DataFrame(data)
dfx = df[["Timestamp", "SUM_kWh"]].groupby(["Timestamp"]).sum()["SUM_kWh"].reset_index()

fig = px.bar(df, x = "Timestamp", y = 'SUM_kWh', color="Name", barmode='group')
fig.add_traces(go.Scatter(x= dfx.Timestamp, y=dfx.SUM_kWh, mode='lines+markers+text', yaxis="y2", line_shape='spline'))
fig.update_layout(template = "plotly_white", paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)",  showlegend=False,
                    yaxis2=dict(
                        overlaying="y",
                        side="right",
                        range=[0, df['SUM_kWh'].max() * 1.2],  # Adjust the range to create space
                        showgrid=False,
                        zeroline=False,
                        title="Total kWh",
                    ),
                    yaxis=dict(
                        title="SUM_kWh (kW)",  # Set title for the left y-axis
                        range=[dfx['SUM_kWh'].min() * 0.8, dfx['SUM_kWh'].max() * 1.3]  # Adjust the range for yaxis
                    ),
                    autosize=True,
                    legend=dict(
                        x=1.05,
                        y=0.5,
                        traceorder="normal",
                ))

fig.update_yaxes(title_text="kWh", secondary_y=False)
fig.show()

@yazouaghe The scatterplot is clipped because the right boundary of yaxis2_range is less than the maximum y2- value for this trace.
Add a number (by trial and error) to dfx['SUM_kWh'].max() instead of multiplying it by a fractionar number in [0, 1].

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

# Create figure with secondary y-axis
fig = make_subplots(specs=[[{"secondary_y": True}]])

# Generate random data
n_rows = 90
n_ids = 4

mongo_ids = [f"INV-{i}" for i in range(1, n_ids + 1)]
timestamps = pd.date_range(start="2024-06-10", periods=n_rows, freq="D")
sum_kwh = np.random.uniform(low=10000, high=40000, size=n_rows)

data = {
    'Name': np.random.choice(mongo_ids, size=n_rows),
    'Timestamp': timestamps,
    'SUM_kWh': sum_kwh
}

df = pd.DataFrame(data)
dfx = df[["Timestamp", "SUM_kWh"]].groupby(["Timestamp"]).sum()["SUM_kWh"].reset_index()

figaux = px.bar(df, x = "Timestamp", y = 'SUM_kWh', color="Name", barmode='group')
for dat in figaux.data:
    fig.add_trace(dat,  secondary_y=False)
fig.add_trace(go.Scatter(x= dfx.Timestamp, y=dfx.SUM_kWh, mode='lines+markers+text', 
                          line_shape='spline'), secondary_y=True)


fig.update_layout(template = "plotly_white", paper_bgcolor="rgba(0,0,0,0)", plot_bgcolor="rgba(0,0,0,0)",  showlegend=False,
                  yaxis=dict(
                        title="SUM_kWh (kW)",  # Set title for the left y-axis
                        range=[0, df['SUM_kWh'].max()*1.2 ]  # Adjust the range for yaxis
                    ),  
                  yaxis2=dict(
                        range=[0, dfx['SUM_kWh'].max()+1e03 ], 
                        
                        showgrid=False,
                        zeroline=False,
                        title="Total kWh",
                        autoshift = True,
                        #fixedrange=True
                    ),
                    
                    autosize=True,  
                    legend=dict(
                        x=1.05,
                        y=0.5,
                        traceorder="normal",
                ))

fig.update_yaxes(title_text="kWh")

Thank you @adamschroeder this works, I only needed to change df.max() for the yaxis and dfx.max() for the yaxis2