2

I am creating a Google colab with some data visualisations of a heatmaps over an image. I've been using the code similar to the one found in the plotly website.

It works fine with the link from the website, but when trying to use a Google Drive link, it does not work. I am using a link in this format: https://docs.google.com/uc?export=download&id=<file-id> The image is shown fine when using it in a markdown field, but not through plotly.

Sample of the code:

fig = px.density_heatmap(df, x="x", y="y",
                         color_continuous_scale = [(0, "rgba(0, 255, 0, 0)"), 
                                                   (0.5, "rgba(0, 255, 0, 0.5)"), 
                                                   (1, "rgba(0, 255, 0, 1)")],
                         height=810, width=1440)
fig.add_layout_image(
        dict(
            source="https://docs.google.com/uc?export=download&id=1JEyyYCse6sWM3yMUwDG2l7XzaGxej-VZ",
            xref="x",
            yref="y",
            x=0,
            y=0,
            sizex=1920,
            sizey=1080,
            sizing="stretch",
            opacity=1,
            layer="below")
)
fig.update_layout(template="plotly_white")
fig.show()

Is there a solution to this, or is it just a case of the library not accounting for the corner case?

EDIT: I was looking to use a Google Drive Link that is not publically available, was hoping I could use the Google Colab credentials. Found a possible answer for that here

Alex_H
  • 95
  • 1
  • 5

1 Answers1

2

The URL that you have prompts to download the image. As mentioned in the plotly documentation you either need the URL of an image or a PIL image object.

A background image can be added to the layout of a figure with fig.add_layout_image or by setting the images parameter of go.Layout. 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')).

That said, you can download the image and read it as PIL image object into python and then use it as the background.

See the example below; since you haven't shared your data, I am using the example dataset on plotly webpage.

import requests
from PIL import Image
import plotly.graph_objects as go

downloading the iamge

## function to dowload google drive image taken from https://stackoverflow.com/a/39225272/6461462
def download_file_from_google_drive(id, destination):
    URL = "https://docs.google.com/uc?export=download"

    session = requests.Session()

    response = session.get(URL, params = { 'id' : id }, stream = True)
    token = get_confirm_token(response)

    if token:
        params = { 'id' : id, 'confirm' : token }
        response = session.get(URL, params = params, stream = True)

    save_response_content(response, destination)    

def get_confirm_token(response):
    for key, value in response.cookies.items():
        if key.startswith('download_warning'):
            return value

    return None

def save_response_content(response, destination):
    CHUNK_SIZE = 32768

    with open(destination, "wb") as f:
        for chunk in response.iter_content(CHUNK_SIZE):
            if chunk: ## filter out keep-alive new chunks
                f.write(chunk)

if __name__ == "__main__":
    file_id = 'TAKE ID FROM SHAREABLE LINK'
    destination = 'DESTINATION FILE ON YOUR DISK'
    download_file_from_google_drive(file_id, destination)
    
## download the image
download_file_from_google_drive("1JEyyYCse6sWM3yMUwDG2l7XzaGxej-VZ", "D:\\test\\gdrive.png")

graph

## read the image into python as a PIL Image object
img = Image.open("D:\\test\\gdrive.png")


## Create figure
fig = go.Figure()

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

## Add images
fig.add_layout_image(
        dict(
            source=img,
            xref="x",
            yref="y",
            x=0,
            y=3,
            sizex=3,
            sizey=3,
            sizing="stretch",
            opacity=0.5,
            layer="below")
)

## Set templates
fig.update_layout(template="plotly_white")

fig.show()

Community
  • 1
  • 1
M--
  • 25,431
  • 8
  • 61
  • 93
  • This works with the specified image, but I was hoping to not having to download the image if possible. Also, for some reason downloading another image that I had did not work. Unsure if it is because of the file type or something else. Just checking that now. – Alex_H Jun 22 '20 at 09:45
  • Figured out why the other image I had did not work. The image is not publically available. Therefore when trying to download it, it does not work. I can probably connect it through google drive, but that would defeat the aim of the question. I can clarify the question, if preferred. – Alex_H Jun 22 '20 at 09:49
  • @Alex_H right practice would be posting a new answer with the updated information and linking to this thread. That way, you'd get better attention and also you steer clear of asking multiple question in one thread which is against How to Ask tutorial. Cheers. – M-- Jun 22 '20 at 14:43
  • Rephrasing the question a bit got an answer, which means there's no elegant way of getting the image. I'll mark your answer as correct, as it answers the initial question – Alex_H Jun 23 '20 at 08:25