0

I'm trying to visualize an image on a plotly plot using px.imshow(). Is it possible to pass in a svg for this rather than an image array?

Thanks in advance.

  • what have you tried? - can you provide access to your svg? – Rob Raymond Sep 21 '21 at 08:23
  • your answer lies here: https://stackoverflow.com/questions/6589358/convert-svg-to-png-in-python **cairo** is being a bit stubborn to install on my Mac – Rob Raymond Sep 21 '21 at 08:59
  • @RobRaymond I have 3 simple svgs and am trying to use plotly imshow for the animation feature as described [here](https://plotly.com/python/imshow/#exploring-3d-images-and-timeseries-with-animationframe) . So I was able to do this using pngs instead of svgs by adding each png to a numpy array and using px.imshow(array) but since this function is an API endpoint and i'm trying to return the plotly to a website, svgs are preferable because the result size is smaller and it's also responsive. I've tried the adding the svg string to a numpy array but that's unsuccessful. – kumquatlemon Sep 21 '21 at 09:03
  • The svgs are literally just this at the moment ` ` – kumquatlemon Sep 21 '21 at 09:05

1 Answers1

0
  • first step is to convert SVG to format required by px.imshow(). Have used cairosvg (this library was somewhat challenging to install)
  • have used approach of creating frames for animation, it maybe possible to combine the images so that it can be done from a 3D array
import numpy as np
import requests, io
import PIL
import cairosvg
import plotly.express as px
import plotly.graph_objects as go

svg_url = "https://logincdn.msauth.net/16.000.28611.4/content/images/microsoft_logo_ee5c8d9fb6248c938fd0dc19370e90bd.svg"
res = requests.get(svg_url)
svgs = [
    '<svg width="100" height="100"><circle cx="20" cy="20" r="10" stroke="black" stroke-width="4" fill="red" /></svg>',
    '<svg width="100" height="100"><circle cx="40" cy="40" r="20" stroke="black" stroke-width="4" fill="red" /></svg>',
    '<svg width="100" height="100"><circle cx="60" cy="60" r="30" stroke="black" stroke-width="4" fill="red" /></svg>',
]

im = [
    PIL.Image.open(io.BytesIO(cairosvg.svg2png(bytestring=svg))).convert("RGBA")
    for svg in svgs
]
go.Figure(data=px.imshow(im[0]).data,
    frames=[go.Frame(data=px.imshow(im).data) for im in im]).update_layout(
    updatemenus=[
        dict(
            type="buttons", buttons=[dict(label="Play", method="animate", args=[None])]
        )
    ]
)
Rob Raymond
  • 29,118
  • 3
  • 14
  • 30