Reputation: 43
How can I show a custom symbol from an image in a scatter plot instead of the following symbols that are provided in dash ?
Here we can use only limited symbol in a graph like this.
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
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()
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()
Upvotes: 2