Taking a variety of tools to embed images to the Jupyter Notebook. A few are: Using img
tag in HTML; converting image to a base64 string representation; using selenium
to render map created by folium
Convert images into base64 string is handy to avoid missing attached files and pack the document into one single file
tag.
from IPython.core.display import HTML, display
img
tag as HTML
¶
img_url = 'https://upload.wikimedia.org/wikipedia/commons/8/84/Hubble_Visible_View_of_Jupiter.jpg'
<img src='https://en.wikipedia.org/wiki/Jupiter#/media/File:Jupiter_and_its_shrunken_Great_Red_Spot.jpg' class='img-fluid'>
HTML(f"
")
Here is the code to embedded image using markdown style

The major drawback using
markdown
is very hard to control the resposiveness of the image. If you reading this on the mobile, it does not scale well to your screen.
This comes handy when you wanted to include a screenshot or a offline image directly to the Jupyter Notebook.
Simply we will convert to the image to
bytes
in format of
string
and give a keyword so that the browser understands this is the data of image
To start, let import
base64
python package
import base64
def convert_img_base64(fpath=None):
'''convert image to bytes and display on jupyter'''
with open(fpath, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
img = f'data:image/png;base64,{encoded_string}'
print(img[:200])
return HTML(f"
{img}>")
# Here is another image of Jupiter
image_path = 'Jupiter.jpg'
convert_img_base64(image_path)
In [8]:
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
X = np.linspace(-np.pi, np.pi, 100)
Y = [np.sin(i) for i in X]
Z = [np.cos(i) for i in X]
# X, Y, Z
from matplotlib.ticker import FormatStrFormatter, MultipleLocator
plt.style.use('default')
plt.rcParams['font.family'] = 'monospace'
fig, ax = plt.subplots(figsize=(8, 4))
ax.plot(X, Y, color='red', lw=2, label='sine(x)')
ax.plot(X, Z, color='blue', lw=2, label='cosine(x)')
ax.axhline(0, color='grey')
ax.axvline(0, color='grey')
# ax.xaxis.set_major_formatter(FormatStrFormatter('%g $\pi$'))
ax.xaxis.set_major_locator(MultipleLocator(np.pi/2))
ax.xaxis.set_minor_locator(MultipleLocator(np.pi/4))
for s in ["top","right","left"]:
ax.spines[s].set_visible(False)
ax.grid(which='both')
ax.legend()
ax.set_title('An Example of Matplotlib with sine and cosine', fontsize=16, y=1.05)
fig.tight_layout()
now we want to get the string representation of the graph and plot back in
first we read content of
fig
object into
bytes
and then
string
we then add property to let the browser know this is a string of image
data:image/png;...
import io
img = io.BytesIO()
fig.savefig(img, format='png', bbox_inches="tight")
# similar to function above
def plt_2_img(fig=None):
'''convert image to bytes and display on jupyter'''
img = io.BytesIO()
fig.savefig(img, format='png', bbox_inches="tight")
encoded_string = base64.b64encode(img.getvalue()).decode("utf-8").replace("\n", "")
img = f'data:image/png;base64,{encoded_string}'
return HTML(f"
{img}>")
plt_2_img(fig=fig)
import folium
from folium.features import DivIcon
import pandas as pd
capitals = pd.read_csv('concap.csv')
capitals.head()
def add_marker(m, row):
'''add marker by each row'''
try:
if row is not None:
location=[row['CapitalLatitude'],row['CapitalLongitude']]
tooltip = f"{row['CapitalName']}"
folium.Circle(location = location,
tooltip = tooltip,
fill=True,
radius = 1_000,
color='maroon'
).add_to(m)
return m
except Exception as e:
print(e)
return None
m = folium.Map(min_zoom=2, max_bounds=True, tiles='cartodbpositron')
for i, row in capitals.iterrows():
add_marker(m, row)
m
# we could save to html format as a seperate file
m.save('captitals.html')
# first we need to copy the right version of geckodriver to the executable path.
# the simpliest approach is to copy directly to bin of virtual environment
!echo $PATH
# now we can render the map to img object with png format
img = m._to_png(3)
encoded_string = base64.b64encode(img).decode("utf-8").replace("\n", "")
img = HTML(f'
{encoded_string}>')
img