Question: import plotly.graph_objects as go fig=go.Figure() cols=['NO2 mug/m^3','NO mug/m^3'] for idx,col in enumerate(cols): for df in [ag,snd]: fig.add_trace(go.Bar(x=df['Date'],y=df[col], name=f'{str(df.Municipality.unique()[0])} {col}')) #fig.add_trace(go.Bar(x=ag['Date'],y=ag['NO mug/m^3'])) fig.update_layout(barmode='group',xaxis=dict(title='Date')) # print(df) fig  In this snippet i take two columns (which are common in both dataframes) and use a bar chart which give me the following result  in this photo we get 4 distinct bars that do not overlay. what i want is to keep this format but to also add a second y axis. But because of the dynamic nature that this format will be used i want it to be versatile. When lets say we have one column ( NO mug/m^3) to not have the second axis. i tried something like this fig = go.Figure() cols = ['NO2 mug/m^3', 'NO mug/m^3'] # Selected gases dfs = [ag, snd] # List of dataframes for df_idx, df in enumerate(dfs): # Iterate over DataFrames (locations) for col_idx, col in enumerate(cols): # Iterate over gases fig.add_trace(go.Bar( x=df['Date'], y=df[col], name=f'{df.Municipality.unique()[0]} - {col}', offsetgroup=str(df_idx), # Group bars per location marker=dict(opacity=0.8), yaxis="y" if col_idx == 0 else "y2" # Assign second gas to secondary y-axis )) # Layout adjustments layout_args = { "barmode": "group", # Ensures bars are placed side-by-side "xaxis": {"title": "Date"}, "legend_title": "Location - Gas" } if len(cols) == 1: layout_args["yaxis"] = {"title": cols[0]} # Single Y-axis case else: layout_args["yaxis"] = {"title": cols[0]} layout_args["yaxis2"] = { "title": cols[1], "overlaying": "y", # Overlay on primary y-axis "side": "right", "showgrid": False } fig.update_layout(**layout_args) fig.show()  From what i tried i got something like the following which is not desireable. is there any way to keep the format of my first image(4 distinct non overlaying bars per x point) while using some condition in order to achive my second axis? thank for your patience

Answer: This is because you are using df_idx to offset the bars. df_idx will only be 0 or 1. When multiple data sets (traces) share a common x-axis (for vertical bars) or y-axis (for horizontal bars), the offsetgroup property allows you to align bars at the same position. Assigning the different offsetgroup value to these traces instructs Plotly to treat them as a different groups for offsetting, ensuring bars with matching coordinates don't overlay. You need to create another variable for offsetting the positions. Example: fig = go.Figure() cols = ['NO2 mug/m^3', 'NO mug/m^3'] # Selected gases dfs = [ag, snd] # List of dataframes offsetgroup = 0 # new variable for offsetting position for col_idx, col in enumerate(cols): # Iterate over gases for df_idx, df in enumerate(dfs): # Iterate over DataFrames (locations) fig.add_trace(go.Bar( x=df['Date'], y=df[col], name=f'{df.Municipality.unique()[0]} - {col}', offsetgroup=str(offsetgroup), # Group bars per location marker=dict(opacity=0.8), yaxis="y" if col_idx == 0 else "y2" # Assign second gas to secondary y-axis )) offsetgroup += 1 # Layout adjustments layout_args = { "barmode": "group", # Ensures bars are placed side-by-side "xaxis": {"title": "Date"}, "legend_title": "Location - Gas" } if len(cols) == 1: layout_args["yaxis"] = {"title": cols[0]} # Single Y-axis case else: layout_args["yaxis"] = {"title": cols[0]} layout_args["yaxis2"] = { "title": cols[1], "overlaying": "y", # Overlay on primary y-axis "side": "right", "showgrid": False } fig.update_layout(**layout_args) fig.show()