Shapes (update_layout) does not work with boxplot

I am plotting subplots (go.Figure()) and attempting to make the pg_colors differ by sublot, using the shape param in update layout. However, even when setting layer=“below”, the shape goes above the box (it does still go above the line). But that’s not useful if I am plotting a boxplot.


Applicable code:

 "shapes": [dict(type="rect", x0=-10, x1=110, y0=-100, y1=150, xref="x2", yref="y2",
            fillcolor="#3A3B3C", layer="below", line=dict(color="#3A3B3C"))]

If you use fig.add_vrect for each subplot, then layer="below" is effective:

import numpy as np
import plotly.graph_objects as go
from scipy.stats import norm
from plotly.subplots import make_subplots
x = np.random.normal(1, 1.2, size=300)
X  =  np.linspace(1-3*1.2, 1+3*1.2, 100)
mypdf=norm.pdf(X, loc=1, scale=1.2)

import as px
df =
fig =, x="day", y="total_bill", color="smoker")

figs=make_subplots(rows=1, cols=2)
figs.add_trace([0], row=1, col=1)
figs.add_trace([1], row=1, col=1)

figs.add_trace(go.Histogram(x=x, histfunc="count", histnorm= "probability density",
                           opacity= 0.7, marker_color= "rgba(4, 217, 255, 255)"), row=1, col=2)
figs.add_trace(go.Scatter(x=X, y=mypdf, mode="lines", line_color="rgba(4, 217, 255, 255)"), row=1, col=2)
figs.update_layout(template="plotly_white", #yaxis_showgrid=False, yaxis2_showgrid=False,
                   width=800, height=400, boxmode="group", showlegend=False, bargap=0.01)

    x0=-1,  x1=4,
    xref='x1', yref='y1', 
    row=1, col=1           
    x0=-3,  x1=5.5,
    xref='x2', yref='y2', 
    row=1, col=2           

The vrect width, i.e. x0 and x1, are set in boxplot by trial and error, while for histogram by observing the xaxis2 range.
This is the plot that displays yaxis, and yaxis2 grid lines :

and this one corresponding to yaxis_showgrid=False, yaxis2_showgrid=False (uncommmented in fig.update_layout):

got it, much appreciated. this solution works with plotly==5.11.0.

@plotmaster422 An update: I figured out how to avoid guessing the x0, x1 values for the vrect definition in each subplot. Replace the figs.add_vrect defined above by:

    x0=0,  x1=1,
    xref='x domain', yref='y1', 
    row=1, col=1           
    x0=0.,  x1=1,
    xref='x domain', yref='y2', 
    row=1, col=2           

i.e. xref='x domain' in both subplots. Such a setting is mentioned in go.layout.Shape reference:

Sets the shape's x coordinate axis. If set to a x axis id (e.g.
    "x" or "x2"), the `x` position refers to a x coordinate. If set
    to "paper", the `x` position refers to the distance from the
    left of the plotting area in normalized coordinates where 0 (1)
    corresponds to the left (right). If set to a x axis ID followed
    by "domain" (separated by a space), the position behaves like
    for "paper", but refers to the distance in fractions of the
    domain length from the left of the domain of that axis: e.g.,
    *x2 domain* refers to the domain of the second x  axis and a x
    position of 0.5 refers to the point between the left and the
    right of the domain of the second x axis.
    The 'xref' property is an enumeration that may be specified as:
      - One of the following enumeration values:
      - A string that matches one of the following regular expressions:
            ['^x([2-9]|[1-9][0-9]+)?( domain)?$'