Secondary X axis in subplot

Hi,

I’m having some trouble with realizing my subplots.
I have two subplots, where one of them has two traces that should be plotted using 2 separate x axes.
The desired effect should look like this:

Unfortunately the ‘kde’ trace is being plotted on the same xaxis as the histogram, and therefore appears out of scale. Also, there is no title for the top xaxis.
the result is this:

import plotly.graph_objects as go
from plotly.subplots import make_subplots    
from scipy.stats import gaussian_kde
import numpy as np

fig = make_subplots(rows=1, cols=2,
                    shared_yaxes=True,
                    shared_xaxes=False,
                    column_widths=[0.8, 0.2],
                    horizontal_spacing=0.01)

np.random.seed(69)
x = np.arange(1, 1000)
y = np.random.randn(1000).cumsum()

fig.add_trace(go.Scatter(
    x=x,
    y=y,
    name='data',
), row=1, col=1)

fig.add_trace(go.Histogram(
y=y,
name='histogram',
), row=1, col=2)

kde = gaussian_kde(y)
x = np.linspace(y.min(), y.max(), 100)
y = kde(x)

fig.add_trace(go.Scatter(
    x=y,
    y=x,
    name='kde',
    xaxis='x3',
), row=1, col=2)

fig.update_layout(
    yaxis=dict(
        title='Y_Axis',
    ),
    xaxis1=dict(
        title='X_Axis_1',
    ),
    xaxis2=dict(
        title='X_Axis_2',
        side='bottom',
    ),
    xaxis3=dict(
        title='X_Axis_3',
        side='top',
    ),
)

fig.update_yaxes(showline=True, linewidth=1, linecolor='black', mirror=True)
fig.update_xaxes(showline=True, linewidth=1, linecolor='black', mirror=True)

fig.show()

Note that I would rather stick to graph_objects alone and not plotly express or figure factory

Alright so the fix required two changes:

  1. adding yaxis=‘y2’ to the ‘kde’ plot instead of specifying which row&column the trace is plotted on.
  2. adding the ‘overlay’ parameter to xaxis that the ‘kde’ is plotted on, so that it overlays on the same plot as xaxis2:
import plotly.graph_objects as go
from plotly.subplots import make_subplots    
from scipy.stats import gaussian_kde
import numpy as np

fig = make_subplots(rows=1, cols=2,
                    shared_yaxes=True,
                    shared_xaxes=False,
                    column_widths=[0.8, 0.2],
                    horizontal_spacing=0.01)

np.random.seed(69)
x = np.arange(1, 1000)
y = np.random.randn(1000).cumsum()

fig.add_trace(go.Scatter(
    x=x,
    y=y,
    name='data',
), row=1, col=1)

fig.add_trace(go.Histogram(
y=y,
name='histogram',
), row=1, col=2)

kde = gaussian_kde(y)
x = np.linspace(y.min(), y.max(), 100)
y = kde(x)

fig.add_trace(go.Scatter(
    x=y,
    y=x,
    name='kde',
    xaxis='x3',
    yaxis='y2', # specify the y axis of the 2nd plot, instead of the column and row
    )
)

fig.update_layout(
    yaxis=dict(
        title='Y_Axis',
    ),
    xaxis1=dict(
        title='X_Axis_1',
    ),
    xaxis2=dict(
        title='X_Axis_2',
        side='bottom',
    ),
    xaxis3=dict(
        title='X_Axis_3',
        side='top',
        overlaying='x2', # overlay the 3rd x axis on the 2nd x axis
    ),
)

fig.update_yaxes(showline=True, linewidth=1, linecolor='black', mirror=True)
fig.update_xaxes(showline=True, linewidth=1, linecolor='black', mirror=True)

fig.show()