Sam
Sam

Reputation: 43

How to show custom symbol in scatter plot in dash?

How can I show a custom symbol from an image in a scatter plot instead of the following symbols that are provided in dash ? enter image description here


Here we can use only limited symbol in a graph like this. enter image description here

I have searched on google but didn't find a single working solution. I need this for a project that I am working on.

Upvotes: 0

Views: 2206

Answers (1)

Derek O
Derek O

Reputation: 19565

You can use the .add_layout_image method to superimpose images of your choice over the markers (making sure you size the images appropriately). This was suggested by @RenaudLN in a Plotly forum post here.

This is just an example using the iris data set, but I created mappings between each species and the url of the image. And I set the size of the images by trial and error (you can adjust this to your liking).

One important thing is that these are not markers connected to the traces, but images covering the actual markers, which is why I made the markers transparent because there's no point in showing them since you want to show the custom images instead. I also hid the legend because it won't have any functionality when you use this workaround – the images you're using to cover the markers can't be shown in the legend, and toggling the entries in the legend won't have any effect on the images that are laid over the trace markers.

import pandas as pd
import plotly.express as px

df = px.data.iris()
fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species")

## make the markers transparent so they don't show up
## hide the legend because there the markers aren't connected to the traces
fig.update_traces(marker=dict(color='rgba(0,0,0,0)'), showlegend=False)

species_to_image_map = {
    "setosa": "https://upload.wikimedia.org/wikipedia/commons/a/a7/Irissetosa1.jpg",
    "versicolor": "https://upload.wikimedia.org/wikipedia/commons/2/27/Blue_Flag%2C_Ottawa.jpg",
    "virginica": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Iris_virginica_2.jpg/1920px-Iris_virginica_2.jpg",
}

for x, y, species in df[["sepal_width","sepal_length","species"]].values:
    fig.add_layout_image(
        dict(
            source=species_to_image_map[species],
            xref="x",
            yref="y",
            xanchor="center",
            yanchor="middle",
            x=x,
            y=y,
            sizex=0.10,
            sizey=0.10,
            sizing="contain",
            opacity=1.0,
            layer="above"
        )
    )

fig.show()

enter image description here

For your code you included in the comments, I get the following result:

import dash
from dash import html
from dash import dcc
import plotly.graph_objects as go
import plotly.express as px
import plotly.graph_objs as go
import pandas as pd
import numpy as np

app = dash.Dash()   

# num = 30
N = 20
x = np.linspace(0, 1, N)
y=np.random.randn(N)+10

fig = px.scatter( x=x,
                  y=y,
)
fig.data[0].update(mode='markers+lines',
             line = dict(shape = 'linear', color = 'rgb(105, 105, 105)', dash = 'dash'),
             connectgaps = True,)
fig.update_layout(
   margin = dict( l = 0,
                  r=100,
                  t=100,
                  b= 0
               ),
   paper_bgcolor="LightSteelBlue",
)



fig.update_traces(marker=dict(color='rgba(0,0,0,0)'), showlegend=False)
for i in range(N):
   fig.add_layout_image(
      dict(
         source="https://upload.wikimedia.org/wikipedia/commons/8/87/PDF_file_icon.svg",
         x=x[i],
         y=y[i],
         xref="x",
         yref="y",
         xanchor="center",
         yanchor="middle",
         sizex=0.10,
         sizey=0.10,
         sizing="contain",
         opacity=1.0,
         layer="above"
      )
   )
fig.show()
app.run_server()

enter image description here

Upvotes: 2

Related Questions