- concept in comments are https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
- these can be used for images within figure in plotly (not demonstrated)
- can be used in HTML (demonstrated by adding additional HTML using BeautifulSoup
- same approach can be used for videos
- there is only a need to use data URIs if your images / videos are files hence cannot be distributed as a URL, hence require encoding in HTML using data URIs
import pandas as pd
import plotly.graph_objects as go
import numpy as np
import plotly.express as px
import base64, io, requests
from PIL import Image
from pathlib import Path
import webbrowser
from bs4 import BeautifulSoup
# data for whare images can be found
df_flag = pd.read_csv(
io.StringIO(
"""country,Alpha-2 code,Alpha-3 code,URL
Australia,AU,AUS,https://www.worldometers.info//img/flags/small/tn_as-flag.gif
New Zealand,NZ,NZL,https://www.worldometers.info//img/flags/small/tn_nz-flag.gif"""
)
)
# ensure that images exist on your file system...
f = Path.cwd().joinpath("flags")
if not f.exists():
f.mkdir()
# download some images and use easy to use filenames...
for r in df_flag.iterrows():
flag_file = f.joinpath(f'{r[1]["Alpha-3 code"]}.gif')
if not flag_file.exists():
r = requests.get(r[1]["URL"], stream=True, headers={"User-Agent": "XY"})
with open(flag_file, "wb") as fd:
for chunk in r.iter_content(chunk_size=128):
fd.write(chunk)
# encode
def b64image(country):
b = io.BytesIO()
im = Image.open(Path.cwd().joinpath("flags").joinpath(f"{country}.gif"))
im.save(b, format="PNG")
b64 = base64.b64encode(b.getvalue())
return b64.decode("utf-8")
df_flag["image"] = df_flag["Alpha-3 code"].apply(b64image)
# create a figure
fig = px.line(df_flag, x="Alpha-2 code", y=df_flag.index)
fh = Path.cwd().joinpath("html.html")
# add some images to HTML
soup = BeautifulSoup(fig.to_html(include_plotlyjs="cdn", div_id="include image"))
d = soup.body
for i, r in df_flag.iterrows():
img = soup.new_tag("img", src="data:image/png;base64,"+r["image"])
d.insert(0, img)
with open(fh, "w") as fp:
fp.write(str(soup))
# launch it...
webbrowser.open("file://" + str(fh), new=2)