Plotly image not showing on Streamlit

I want to add an image as a watermark on my plotly charts. Running the code below in a notebook works fine, but on Streamlit the image doesn’t show:

import plotly.graph_objects as go

fig = go.Figure()

fig.add_trace(go.Scatter(x=[0, 0.5, 1, 2, 19], y=[1.23, 2.5, 0.42, 3, 1]))

fig.add_layout_image(
        dict(
            source="https://i0.wp.com/scannerdabolsa.com.br/wp-content/uploads/2021/03/cropped-LOGO-SCANNER-DA-BOLSA.jpg",
            xref="paper",
            yref="paper",
            x=0.5,
            y=1,
            sizex=0.5,
            sizey=0.5,
            #sizing="stretch",
            opacity=0.5,
            layer="below")
)


st.plotly_chart(fig, use_container_width=True)   


Hi @eduardot80, welcome to the community!

What versions of plotly and streamlit are you using? The image as watermark appears in Streamlit when I run your code. The code works with streamlit==1.11.0 and plotly==5.8.2.

If you’re using older versions, I would suggest upgrading to the above versions.

Hi snehankekre, thanks for the help!

I upgraded to streamlit==1.11.0 and plotly==5.9.0 but still have the problem. Also deployed to heroku and the image doesn’t show there either. This is really weird because apart from that, every plotly chart I have built works fine.

It would help if you could share a GitHub repo with the same code and a link to the streamlit cloud app.

Hey

I’m having the same problem. Have published a github repo: GitHub - mileseverett/streamlit_1

System info: Windows 11 but using Windows Linux Subsystem Ubuntu 20.4 LTS.

Environment is created from the requirements.txt file.

When I run the code with “streamlit run myapp.py” I see:


rather than:


when run from a juypter notebook using only plotly.

Hope this helps find the bug!

Thanks
Miles

Edit: Have just tested on a Ubuntu system rather than Ubuntu through WSL. Still has the same result. Also tested with streamlit==1.11.0 and plotly==5.9.0.

Solution found, rather than passing image directory/URL to the add_layout_image dictionary, import image using PIL.Image and then pass a PIL.Image object as source.

not working:

import streamlit as st

import plotly.graph_objects as go

# Create figure
fig = go.Figure()

fig.add_layout_image(
        dict(
            source="images/de_ancient.png",
            xref="x",
            yref="y",
            x=0,
            y=0,
            sizex=1024,
            sizey=1024,
            # sizing="stretch",
            opacity=1,
            layer="below")
)


fig.add_trace(go.Scatter(x=[100,100,200,50], y=[100,200,100,50], fill="toself"))

fig.update_layout(template="plotly_white")

fig.update_xaxes(showgrid=False, range=(0, 1024))
fig.update_yaxes(showgrid=False, scaleanchor='x', range=(1024, 0))

st.plotly_chart(fig)

working:

import streamlit as st

import plotly.graph_objects as go

from PIL import Image

img = Image.open("images/de_ancient.jpg")

# Create figure
fig = go.Figure()

fig.add_layout_image(
        dict(
            source=img,
            xref="x",
            yref="y",
            x=0,
            y=0,
            sizex=1024,
            sizey=1024,
            visible=True,
            # sizing="stretch",
            opacity=1,
            layer="below")
)


# fig.add_trace(go.Scatter(x=[100,100,200,50], y=[100,200,100,50], fill="toself"))

fig.update_layout(template="plotly_white")

fig.update_xaxes(showgrid=False, range=(0, 1024))
fig.update_yaxes(showgrid=False, scaleanchor='x', range=(1024, 0))

st.plotly_chart(fig)

Glad you found the solution, @mileseverett :balloon:

The Plotly docs say:

The source attribute of a go.layout.Image can be the URL of an image, or a PIL Image object (from PIL import Image; img = Image.open('filename.png') ).

So you were right to replace the file pointer with a PIL Image object. :smile: