Search code examples
pythonimageplotlyaddition

How to add images instead of dots in a plotly scatter plot (python)


Lets say I have this scatter plot in plotly:

import plotly.express as px
fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16])
fig.show()

enter image description here

But instead of the dots I want to add different Images on those particular positions. Something like this:

enter image description here

Is that possible with plotly? I know that you can add Images but I dont know how to pass the exact coordinates of position where the images should be shown.

I apprecaite your time! Thank you.


Solution

    • a few points on answer
      • no reference was provided to images to use, so downloaded some from kaggle. Couldn't find emojis. This bulks up code to do this...
      • Plotly Express is used without a data frame in question. So have kept to this. This then means loop through x&y values in trace to get position of images
      • effectively image used is random, could be selected based on features of data

    enter image description here

    import plotly.express as px
    import kaggle.cli
    import sys, requests
    from pathlib import Path
    from zipfile import ZipFile
    import urllib
    from PIL import Image
    
    # fmt: off
    # download some images to demonstrate
    url = "https://www.kaggle.com/anzhemeng/nfl-team-logos"
    sys.argv = [sys.argv[0]] + f"datasets download {urllib.parse.urlparse(url).path[1:]}".split(" ")
    kaggle.cli.main()
    zfile = ZipFile(f'{urllib.parse.urlparse(url).path.split("/")[-1]}.zip')
    # fmt: on
    zfile.extractall("nfl-logos")
    
    fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16])
    
    # question did not use a dataframe,  so will use x & y from the figure trace
    # just a selection of images, used NFL images given don't have emojis
    for x,y, png in zip(fig.data[0].x, fig.data[0].y, Path.cwd().joinpath("nfl-logos").glob("*.png")):
        fig.add_layout_image(
            x=x,
            y=y,
            source=Image.open(png),
            xref="x",
            yref="y",
            sizex=2,
            sizey=2,
            xanchor="center",
            yanchor="middle",
        )
        
    fig