9

I am trying to create different subplot and I want for each subplot to have a different background color. I'm using plotly and it makes the thing a little bit more difficult. Any idea? I think the equivalent in matplot is face_color or something like this.

fig = make_subplots(rows=1, cols=2)

fig.add_trace(
    go.Scatter(
        x=list(range(sample_points)),
        y=data_gx.iloc[scene],
        name='X-axis',
        line=dict(color='green', width=2)
    ),
    row=1, col=1
)

fig.add_trace(
    go.Scatter(
        x=list(range(sample_points)),
        y=data_ax.iloc[scene],
        name='X-axis',
        line=dict(color='green', width=2)
    ),
    row=1, col=2
)
1
  • If you want to run the code in your local and check the output, change x and y with this of both graphs so just to see some output. """ x=list(range(10)), y=list(range(10)), """ Commented May 6, 2020 at 9:24

5 Answers 5

8

Unfortunately, it still does not seem that you can set different background colors for the different subplots directly:

The background color is set in layout for the figure: plot_bgcolor='rgb(245,245,240)'. At the moment you cannot change the backround of a particular subplot.

BUT you are free to place shapes anywhere you'd like on both subplots by referencing both x axes through xref=x and xref=x2 in fig.update_layout(shapes=dict()). And if you make sure to tweak a few other parameters as well like the zeroline and layer='below' you'll get a result thats pretty good:

enter image description here

Complete code:

# imports
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import pandas as pd
import numpy as np

# data
df = pd.DataFrame({'Index': {0: 1.0,
                              1: 2.0,
                              2: 3.0,
                              3: 4.0,
                              4: 5.0,
                              5: 6.0,
                              6: 7.0,
                              7: 8.0,
                              8: 9.0,
                              9: 10.0},
                             'A': {0: 15.0,
                              1: 6.0,
                              2: 5.0,
                              3: 4.0,
                              4: 3.0,
                              5: 2.0,
                              6: 1.0,
                              7: 0.5,
                              8: 0.3,
                              9: 0.1},
                             'B': {0: 1.0,
                              1: 4.0,
                              2: 2.0,
                              3: 5.0,
                              4: 4.0,
                              5: 6.0,
                              6: 7.0,
                              7: 2.0,
                              8: 8.0,
                              9: 1.0},
                             'C': {0: 12.0,
                              1: 6.0,
                              2: 5.0,
                              3: 4.0,
                              4: 3.0,
                              5: 2.0,
                              6: 1.0,
                              7: 0.5,
                              8: 0.2,
                              9: 0.1}})
# set up plotly figure
fig = make_subplots(1,2)

# add first bar trace at row = 1, col = 1
fig.add_trace(go.Bar(x=df['Index'], y=df['A'],
                     name='A',
                     marker_color = 'green',
                     opacity=0.4,
                     marker_line_color='rgba(0,0,0,0)',
                     marker_line_width=2),
              row = 1, col = 1)

# add first scatter trace at row = 1, col = 1
fig.add_trace(go.Scatter(x=df['Index'], y=df['B'], line=dict(color='red'), name='B'),
              row = 1, col = 1)

# add first bar trace at row = 1, col = 2
fig.add_trace(go.Bar(x=df['Index'], y=df['C'],
                     name='C',
                     marker_color = 'green',
                     opacity=0.4,
                     marker_line_color='rgba(0,0,0,0)',
                    marker_line_width=2),
              row = 1, col = 2)

fig.update_layout(plot_bgcolor='rgba(0,0,0,0)')

# Define gridlines and zerolines
# => an invisible zerolines looks better
# in this scenario
fig.update_layout(xaxis=dict(showgrid=False, zeroline=False),
                  yaxis=dict(showgrid=True, zeroline=False),
                  xaxis2=dict(showgrid=False, zeroline=False),
                  yaxis2=dict(showgrid=True, zeroline=False),

)

fig.update_layout(
    shapes=[
        # 1st highlight during Feb 4 - Feb 6
 dict(
            type="rect",
            xref="x",
            yref="paper",
            x0=df['Index'].iloc[0]-1,
            y0=-0.001,
            x1=df.index[-1]+2,
            y1=1,
            fillcolor="steelblue",
            opacity=0.5,
            layer="below",
            line_width=0,
        ),
        # 2nd highlight during Feb 20 - Feb 23
        dict(
            type="rect",
            xref="x2",
            yref="paper",
            x0=df['Index'].iloc[0]-1,
            y0=-0.001,
            x1=df.index[-1]+2,
            y1=1,
            fillcolor="firebrick",
            opacity=0.5,
            layer="below",
            line_width=0,
        )
    ]
)

fig.show()
Sign up to request clarification or add additional context in comments.

1 Comment

This is aprox what I want to do but instead of having the same color background, I want for each plot a different background. For the first lightblue, for the second red or something else. Thank you
7

Try:

fig.update_layout(plot_bgcolor = "white")

fig.show()

Comments

3

I think you can easily change the background with the paper_bgcolorand plot_bgcolor layout options.

Here is a related question posted long ago: Python -- Setting Background color to transparent in Plotly plots

Comments

2
fig.add_trace(go.Scatter(x=[-1,2],y= [2,2],fill='tozeroy'),row=1, col=1)

This worked for me. This will draw a line from (-1,2) to (2,2) and will color everything below this points. It can help you color your background of each subplot just by adding in the row and col of subplots. It worked for me, I hope it will work for you too.

1 Comment

That works too. But now you have to make sure that the trace you're using to give a background color does not cover any other traces. With shapes you have the option to specify the placement as layer='below' to prevent that from happening.
1

Use xref='x domain' & yref='y domain' can directly paint a whole subplot area without put any axis data into the shapes definition. Only x,x2,x3...y,y2,y3 can be used according to official documentation. The example is as below.

fig.update_layout(
    shapes=[
        dict(
            type="rect",
            xref="x domain",
            yref="y domain",
            x0=0, y0=0, x1=1, y1=1,
            fillcolor="blue",
            opacity=0.5,
            layer="below",
            line_width=0,
        ),
        dict(
            type="rect",
            xref="x2 domain",
            yref="y2 domain",
            x0=0, y0=0, x1=1, y1=1,
            fillcolor="#D62728",
            opacity=0.5,
            layer="below",
            line_width=0,
        ),
    ]
)

This is inspired by the answer by @vestland of this post.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.