Jekyll, Say Hi to Jupyter Notebook Again!
jekyll
jupyter_notebook
So I've spent the weekend figuring out how to properly embed Jupyter notebooks into my Jekyll site. Overall, I'm happy with my results. I managed to adjust the font-colors of the various CSS classess and embed my plots nicely in here. I also learned how to include my own images and embed audio into my Jupyter notebooks and have them play after the conversion to html.
My current procedure for doing this is as follows:
- Download Jupyter Notebook (.ipynb) as a .html
- Copy the contents of the resulting html file into a Jekyll post with the appropriate header
- Remove the DOCTYPE and html lines contained within the html file made from the Jupyter notebook
In addition to those steps, I also slightly modified the 'default.html' file and made a 'jupyter.html' file based on the files that came from the Jekyll website template I'm using. This allowed me to preserve the post headers and control the footers of my site since they were behaving kinda wonky (i.e., the image associated with the post was not showing up, the jupyter notebook was off-center, and the footer links were messed up). That being said, if you follow the above three steps, you'll be able to see your Jupyter notebook in your Jekyll site.
I also tried (perhaps an instance of me trying to get too fancy too soon) to embed interactive plots using plotly in my jekyll site. Unfortunately, that has proven to be quite challenging so far since the conversion from the .ipynb to html using nbconv seems to have an issue with the javascript associated with plotly. I've tried modifying the javascript but haven't been successful yet in rendering my interactive visualizations.
If you are trying to use plotly in your Jupyter Notebooks and have them displayed in your Jekyll site, here are a few links that may be useful to you:
- https://davistownsend.github.io/blog/PlotlyBloggingTutorial/
- https://stackoverflow.com/questions/50546971/embedding-plotly-interactive-graphs-into-blog-without-losing-animation
- https://stackoverflow.com/questions/72378397/about-plotly-how-can-i-post-it-for-my-github-pages
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import seaborn as sns
import numpy as np
import pandas as pd
import random
import json
from IPython.display import display, HTML
#Hi!
print("Hello Jekyll from the Jupyter Notebook!! :]")
Hello Jekyll from the Jupyter Notebook!! :]
#Make random data to plat
xs = [random.gauss(0, 10) for _ in range(100)]
ys = [random.gauss(0, 10)for _ in range(100)]
zs = [random.gauss(0, 10) for _ in range(100)]
#Make a scatter plot from random data
sns.set(rc={'figure.figsize':(16.7,8.27)})
sns.set(font_scale = 2)
plt.scatter(xs, ys)
plt.xlabel("X")
plt.ylabel("Y")
plt.title("Random plot")
plt.show()
#Make histogram of generated data
sns.color_palette("mako", as_cmap=True)
sns.histplot(ys, bins = 20, discrete = True, kde = True, color = 'red', alpha=0.5)
sns.histplot(xs, bins = 20, discrete = True, kde = True, color = 'blue', alpha=0.5)
sns.set(rc={'figure.figsize':(16.7,8.27)})
sns.set(font_scale = 2)
plt.legend(labels=["Rand y","Rand x"])
<matplotlib.legend.Legend at 0x2b0aef26e48>
#Make a 3D parametric curve
ax = plt.figure().add_subplot(projection='3d')
sns.set(rc={'figure.figsize':(8.7,8.27)})
# Prepare arrays x, y, z
theta = np.linspace(-4 * np.pi, 4 * np.pi, 100)
z = np.linspace(-2, 2, 100)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
ax.plot(x, y, z, label='parametric curve')
ax.legend()
plt.show()
#Quiver plot
ax = plt.figure().add_subplot(projection='3d')
# Make the grid
x, y, z = np.meshgrid(np.arange(-0.8, 1, 0.2),
np.arange(-0.8, 1, 0.2),
np.arange(-0.8, 1, 0.8))
# Make the direction data for the arrows
u = np.cos(np.pi * x) * np.cos(np.pi * y) * np.cos(np.pi * z)
v = -np.cos(np.pi * x)**2 * np.sin(np.pi * y) * np.cos(np.pi * z)
w = (np.sqrt(2.0 / 3.0) * np.cos(np.pi * x) * np.tan(np.pi * y) *
np.sin(np.pi * z))
ax.quiver(x, y, z, u, v, w, length=0.15, normalize=True)
plt.show()
#3D surface volcano plot
from pylab import *
rcParams['figure.figsize'] = 7,5
# Get the data (csv file is hosted on the web)
url = 'https://raw.githubusercontent.com/holtzy/The-Python-Graph-Gallery/master/static/data/volcano.csv'
data = pd.read_csv(url)
# Transform it to a long format
df=data.unstack().reset_index()
df.columns=["X","Y","Z"]
# And transform the old column name in something numeric
df['X']=pd.Categorical(df['X'])
df['X']=df['X'].cat.codes
# Make the plot
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_trisurf(df['Y'], df['X'], df['Z'], cmap=plt.cm.viridis, linewidth=0.2)
plt.show()
# to Add a color bar which maps values to colors.
fig = plt.figure()
ax = fig.gca(projection='3d')
surf=ax.plot_trisurf(df['Y'], df['X'], df['Z'], cmap=plt.cm.viridis, linewidth=0.2)
fig.colorbar( surf, shrink=0.5, aspect=5)
plt.show()
# Rotate it
fig = plt.figure()
ax = fig.gca(projection='3d')
surf=ax.plot_trisurf(df['Y'], df['X'], df['Z'], cmap=plt.cm.viridis, linewidth=0.2)
ax.view_init(30, 45)
plt.show()
# Other palette
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_trisurf(df['Y'], df['X'], df['Z'], cmap=plt.cm.jet, linewidth=0.01)
plt.show()
C:\Users\vmurc\anaconda3\lib\site-packages\ipykernel_launcher.py:19: MatplotlibDeprecationWarning: Calling gca() with keyword arguments was deprecated in Matplotlib 3.4. Starting two minor releases later, gca() will take no keyword arguments. The gca() function should only be used to get the current axes, or if no axes exist, create new axes with default keyword arguments. To create a new axes with non-default arguments, use plt.axes() or plt.subplot().
C:\Users\vmurc\anaconda3\lib\site-packages\ipykernel_launcher.py:25: MatplotlibDeprecationWarning: Calling gca() with keyword arguments was deprecated in Matplotlib 3.4. Starting two minor releases later, gca() will take no keyword arguments. The gca() function should only be used to get the current axes, or if no axes exist, create new axes with default keyword arguments. To create a new axes with non-default arguments, use plt.axes() or plt.subplot(). C:\Users\vmurc\anaconda3\lib\site-packages\ipykernel_launcher.py:27: MatplotlibDeprecationWarning: Auto-removal of grids by pcolor() and pcolormesh() is deprecated since 3.5 and will be removed two minor releases later; please call grid(False) first.
C:\Users\vmurc\anaconda3\lib\site-packages\ipykernel_launcher.py:32: MatplotlibDeprecationWarning: Calling gca() with keyword arguments was deprecated in Matplotlib 3.4. Starting two minor releases later, gca() will take no keyword arguments. The gca() function should only be used to get the current axes, or if no axes exist, create new axes with default keyword arguments. To create a new axes with non-default arguments, use plt.axes() or plt.subplot().
C:\Users\vmurc\anaconda3\lib\site-packages\ipykernel_launcher.py:39: MatplotlibDeprecationWarning: Calling gca() with keyword arguments was deprecated in Matplotlib 3.4. Starting two minor releases later, gca() will take no keyword arguments. The gca() function should only be used to get the current axes, or if no axes exist, create new axes with default keyword arguments. To create a new axes with non-default arguments, use plt.axes() or plt.subplot().
# 3D Scatter Plot
df=pd.DataFrame({'X': range(1,101), 'Y': np.random.randn(100)*15+range(1,101), 'Z': (np.random.randn(100)*15+range(1,101))*2 })
# plot
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(df['X'], df['Y'], df['Z'], c='purple', s=60)
plt.show()
#Another 3D Surface
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
# Make data.
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
# Plot the surface.
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm,
linewidth=0, antialiased=False)
# Customize the z axis.
ax.set_zlim(-1.01, 1.01)
ax.zaxis.set_major_locator(LinearLocator(10))
# A StrMethodFormatter is used automatically
# Add a color bar which maps values to colors.
fig.colorbar(surf, shrink=0.5, aspect=5)
plt.show()
C:\Users\vmurc\anaconda3\lib\site-packages\ipykernel_launcher.py:21: MatplotlibDeprecationWarning: Auto-removal of grids by pcolor() and pcolormesh() is deprecated since 3.5 and will be removed two minor releases later; please call grid(False) first.
#3D Object
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
# Make data
u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)
x = 10 * np.outer(np.cos(u), np.sin(v))
y = 10 * np.outer(np.sin(u), np.sin(v))
z = 10 * np.outer(np.ones(np.size(u)), np.cos(v))
# Plot the surface
ax.plot_surface(x, y, z)
plt.show()
#Hat plot :]]]
from matplotlib.ticker import LinearLocator
ax = plt.figure().add_subplot(projection='3d')
# Make data.
X = np.arange(-5, 5, 0.25)
xlen = len(X)
Y = np.arange(-5, 5, 0.25)
ylen = len(Y)
X, Y = np.meshgrid(X, Y)
R = np.arcsinh(X**4 - Y**3)
Z = np.sin(R)
# Create an empty array of strings with the same shape as the meshgrid, and
# populate it with two colors in a checkerboard pattern.
colortuple = ('y', 'b')
colors = np.empty(X.shape, dtype=str)
for y in range(ylen):
for x in range(xlen):
colors[y, x] = colortuple[(x + y) % len(colortuple)]
# Plot the surface with face colors taken from the array we made.
surf = ax.plot_surface(X, Y, Z, facecolors=colors, linewidth=0)
# Customize the z axis.
ax.set_zlim(-1, 1)
ax.zaxis.set_major_locator(LinearLocator(6))
plt.show()
#Voxel plot
import matplotlib.colors
def midpoints(x):
sl = ()
for i in range(x.ndim):
x = (x[sl + np.index_exp[:-1]] + x[sl + np.index_exp[1:]]) / 2.0
sl += np.index_exp[:]
return x
# prepare some coordinates, and attach rgb values to each
r, theta, z = np.mgrid[0:1:11j, 0:np.pi*2:25j, -0.5:0.5:11j]
x = r*np.cos(theta)
y = r*np.sin(theta)
rc, thetac, zc = midpoints(r), midpoints(theta), midpoints(z)
# define a wobbly torus about [0.7, *, 0]
sphere = (rc - 0.7)**2 + (zc + 0.2*np.cos(thetac*2))**2 < 0.2**2
# combine the color components
hsv = np.zeros(sphere.shape + (3,))
hsv[..., 0] = thetac / (np.pi*2)
hsv[..., 1] = rc
hsv[..., 2] = zc + 0.5
colors = matplotlib.colors.hsv_to_rgb(hsv)
# and plot everything
ax = plt.figure().add_subplot(projection='3d')
ax.voxels(x, y, z, sphere,
facecolors=colors,
edgecolors=np.clip(2*colors - 0.5, 0, 1), # brighter
linewidth=0.5)
plt.show()
#Triangular Surface
import matplotlib.tri as mtri
fig = plt.figure(figsize=plt.figaspect(0.3))
# Make parameter spaces radii and angles.
n_angles = 36
n_radii = 8
min_radius = 0.25
radii = np.linspace(min_radius, 0.95, n_radii)
angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False)
angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1)
angles[:, 1::2] += np.pi/n_angles
# Map radius, angle pairs to x, y, z points.
x = (radii*np.cos(angles)).flatten()
y = (radii*np.sin(angles)).flatten()
z = (np.cos(radii)*np.cos(3*angles)).flatten()
# Create the Triangulation; no triangles so Delaunay triangulation created.
triang = mtri.Triangulation(x, y)
# Mask off unwanted triangles.
xmid = x[triang.triangles].mean(axis=1)
ymid = y[triang.triangles].mean(axis=1)
mask = xmid**2 + ymid**2 < min_radius**2
triang.set_mask(mask)
# Plot the surface.
ax = fig.add_subplot(1, 2, 2, projection='3d')
ax.plot_trisurf(triang, z, cmap=plt.cm.CMRmap)
plt.show()
#Hinton diagram
def hinton(matrix, max_weight=None, ax=None):
"""Draw Hinton diagram for visualizing a weight matrix."""
ax = ax if ax is not None else plt.gca()
if not max_weight:
max_weight = 2 ** np.ceil(np.log2(np.abs(matrix).max()))
ax.patch.set_facecolor('gray')
ax.set_aspect('equal', 'box')
ax.xaxis.set_major_locator(plt.NullLocator())
ax.yaxis.set_major_locator(plt.NullLocator())
for (x, y), w in np.ndenumerate(matrix):
color = 'white' if w > 0 else 'black'
size = np.sqrt(abs(w) / max_weight)
rect = plt.Rectangle([x - size / 2, y - size / 2], size, size,
facecolor=color, edgecolor=color)
ax.add_patch(rect)
ax.autoscale_view()
ax.invert_yaxis()
if __name__ == '__main__':
# Fixing random state for reproducibility
np.random.seed(19680801)
hinton(np.random.rand(20, 20) - 0.5)
plt.show()
ax = plt.axes(projection='3d')
# Data for a three-dimensional line
zline = np.linspace(0, 15, 1000)
xline = np.sin(zline)
yline = np.cos(zline)
ax.plot3D(xline, yline, zline, 'gray')
# Data for three-dimensional scattered points
zdata = 15 * np.random.random(100)
xdata = np.sin(zdata) + 0.1 * np.random.randn(100)
ydata = np.cos(zdata) + 0.1 * np.random.randn(100)
ax.scatter3D(xdata, ydata, zdata, c=zdata, cmap='Greens');
#Mobius Strip
theta = np.linspace(0, 2 * np.pi, 30)
w = np.linspace(-0.25, 0.25, 8)
w, theta = np.meshgrid(w, theta)
phi = 0.5 * theta
# radius in x-y plane
r = 1 + w * np.cos(phi)
x = np.ravel(r * np.cos(theta))
y = np.ravel(r * np.sin(theta))
z = np.ravel(w * np.sin(phi))
# triangulate in the underlying parametrization
from matplotlib.tri import Triangulation
tri = Triangulation(np.ravel(w), np.ravel(theta))
ax = plt.axes(projection='3d')
ax.plot_trisurf(x, y, z, triangles=tri.triangles,
cmap='viridis', linewidths=0.2);
ax.set_xlim(-1, 1); ax.set_ylim(-1, 1); ax.set_zlim(-1, 1);
Embedding an image via html onto Jupyter Notbook
Here's a picture of my cat for you :]
Embedding an audio file into Jupyter Notbook
Below is a sameple of my guitar playing :]
#Loading an audio file into notebook
IPython.display.Audio("CrimsonCloverCover.mp3")