How to add subplot's background image by using graph_object?

Hello, I am trying to add background image into all subplots.

Inserting a background image for one graph was successful.

but I could not success in subplots.

I used the following code by referring to the document.
( Images | Python | Plotly)

image_dict = dict(
    source=image
    xref='x',
    yref='y',
    x=0,
    y=height,
    sizex=width,
    sizey=height,
    layer='below',
    row=1,
    col=2
)

fig.add_layout_image(image_dict)

but this code is available only in plotly.express.

Is there any way to add background image into all subplots using plotly.graph_objects?

@hyojoo.cho
Here is an example of setting a layout image for each subplot. You can use an image
from an online source or a local image. My example uses local images.
For online source see Plotly example: https://plotly.com/python/images/

import plotly.graph_objects as go
from plotly.subplots import make_subplots
import base64

image1_filename = 'img_lights.png'
polar_light = base64.b64encode(open(image1_filename, 'rb').read())
image2_filename = 'img_snowtops.png'
snow = base64.b64encode(open(image2_filename, 'rb').read())

fig = make_subplots(
    rows=2, cols=1, subplot_titles=("Title 1", "Title 2"),
    vertical_spacing=0.075
)

fig.add_trace(go.Scatter(x= [1, 1.75, 2.5, 3.5], y=[-1, 3, 0, 3,  5],
                         mode='markers',
                         marker_size=20,
                         marker_color="#ffd700"),
              row=1, col=1)

fig.add_trace(go.Scatter(x= [1, 1.75, 2.5, 3.5], y=[4, 2, 6, 3,  5], mode='markers',
                         marker_symbol='triangle-down',
                         marker_size=20, marker_color='red'),
              row=2, col=1)
fig.update_layout(width=850, height=700,
                images= [dict(
                    source='data:image/png;base64,{}'.format(polar_light.decode()),
                    xref="paper", yref="paper",
                    x=0, y=1,  #position of the upper left corner of the image in subplot 1,1
                    sizex=1, sizey=0.46, #sizex, sizey are set by trial and error
                    xanchor="left",
                    yanchor="top",
                    sizing="stretch",
                    layer="below"),
                    dict(
                    source='data:image/png;base64,{}'.format(snow.decode()),
                    xref="paper", yref="paper",
                    x=0, y=0.46,  #position of the upper left corner of the image in subplot 2,1
                    sizex=1, sizey=0.46,
                    xanchor="left",
                    yanchor="top",
                    sizing="stretch",
                    layer="below")    ])

fig.update_xaxes(showgrid=False, zeroline=False)
fig.update_yaxes(showgrid=False, zeroline=False)

1 Like

I check it so lately. Thank you so much!
i will try it :slight_smile:

Hi, just a quick note :
Using xref=β€œx” and yref=β€œy1” or β€œy2” enable you to stick each image with each subplot without having to guess the paper coordinates.

1 Like

I just saw this old comment. Don’t express an opinion, please, without an example. Just try to experiment following your idea and you’ll see that sizex and sizey should be set also by trial and error.

As for 2024 the best solution is as follows:

fig.update_layout(width=850, height=700,
                images= [dict(
                    source='data:image/png;base64,{}'.format(polar_light.decode()),
                    xref="x domain", yref="y domain",
                    x=0, y=1,  #position of the upper left corner of the image in subplot 1,1
                    sizex=1, sizey=1, 
                    xanchor="left",
                    yanchor="top",
                    sizing="stretch",
                    layer="below"),
                    dict(
                    source='data:image/png;base64,{}'.format(snow.decode()),
                    xref="x2 domain", yref="y2 domain",
                    x=0, y=1, 
                    sizex=1, sizey=1,
                    xanchor="left",
                    yanchor="top",
                    sizing="stretch",
                    layer="below")    ])