Nanocartography: Planning for success in analytical electron microscopy
Contents
Superellipse
Article - Nanocartography Interactivity - Superellipse figure v2 - Colin update
# imports for widgets
from IPython.display import HTML, display, Math
import ipywidgets as widgets
from ipywidgets import FloatLogSlider, FloatSlider, Layout, HBox, VBox, Label
# from IPython.display import display, Math
# importing required libraries
import numpy as np
import matplotlib.pyplot as plt
# for creating a responsive plot
%matplotlib widget
# Define super ellipse function
def calc_superellipse(
theta,
r,
a,
b,
):
"""
Super ellipse function definition. Inputs are angle theta, shape factor r, and limits (a,b).
Returns alpha and beta for all 4 quadrants.
"""
pos_alpha = a * (np.cos(theta)**(2/r))
pos_beta = b * (np.sin(theta)**(2/r))
alpha = np.hstack((
pos_alpha,
-np.flip(pos_alpha),
-pos_alpha,
np.flip(pos_alpha),
))
beta = np.hstack((
pos_beta,
np.flip(pos_beta),
-pos_beta,
-np.flip(pos_beta),
))
return alpha,beta
# Inputs
r_init = 3.3
a_init = 36.0
b_init = 32.0
ab_range = (5, 45)
ab_plot_range = 50
r_range = (1,10)
step = 0.01
theta = np.linspace(
0.0,
np.pi/2,
90,
endpoint=False)
fontsize = 18
dpi = 72
# initialize figure
plt.close('all')
plt.ioff()
fig = plt.figure(figsize=(440/dpi, 400/dpi), dpi=dpi)
ax = fig.add_axes((0.16, 0.12, 0.80, 0.86))
fig.canvas.resizable = False
fig.canvas.header_visible = False
fig.canvas.footer_visible = False
fig.canvas.toolbar_visible = False
fig.canvas.layout.width = '470px'
fig.canvas.toolbar_position = 'bottom'
# Transparent figure
fig.set_frameon(False)
ax.patch.set_visible(False)
ax.set_xlim((-ab_plot_range,ab_plot_range))
ax.set_ylim((-ab_plot_range,ab_plot_range))
ax.set_xlabel(r'$\alpha$ (degrees)', fontsize = fontsize)
ax.set_ylabel(r'$\beta$ (degrees)', fontsize = fontsize)
ax.tick_params(axis='both', which='major', labelsize = fontsize - 4)
c = (0.4,0.4,0.4)
ax.spines['bottom'].set_color(c)
ax.spines['top'].set_color(c)
ax.spines['right'].set_color(c)
ax.spines['left'].set_color(c)
ax.grid(which='major', color=c, linestyle='-', alpha=0.7)
ax.grid(which='minor', color=c, linestyle='-', alpha=0.4)
ax.minorticks_on()
ax.xaxis.label.set_color(c)
ax.yaxis.label.set_color(c)
ax.tick_params(axis='both', colors=c)
# plot the superellipse
rab = [r_init, a_init, b_init]
alpha,beta = calc_superellipse(
theta,
rab[0],
rab[1],
rab[2],
)
superellipse = ax.fill(
alpha,
beta,
edgecolor = (1,0,0,1),
facecolor = (1,0,0,0.3),
lw = 3,
)
# superellipse = superellipse_outer.get_paths()[0]
# dummy = ax.fill_between(t, 0, f(t, amp_slider.val, freq_slider.val), alpha=0)
# dp = dummy.get_paths()[0]
# dummy.remove()
# #update the vertices of the PolyCollection
# fill.set_paths([dp.vertices])
# update functions
def update_r(change):
rab[0] = change['new']
alpha,beta = calc_superellipse(
theta,
rab[0],
rab[1],
rab[2],
)
superellipse[0].set_xy(np.vstack((alpha,beta)).T)
fig.canvas.draw_idle()
return None
def update_a(change):
rab[1] = change['new']
alpha,beta = calc_superellipse(
theta,
rab[0],
rab[1],
rab[2],
)
superellipse[0].set_xy(np.vstack((alpha,beta)).T)
fig.canvas.draw_idle()
return None
def update_b(change):
rab[2] = change['new']
alpha,beta = calc_superellipse(
theta,
rab[0],
rab[1],
rab[2],
)
superellipse[0].set_xy(np.vstack((alpha,beta)).T)
fig.canvas.draw_idle()
return None
# Add the interactive widgets
slider_r = FloatLogSlider(
value=rab[0],
min=np.log10(r_range[0]),
max=np.log10(r_range[1]),
step = step,
continuous_update=True,
orientation='horizontal',
indent=True,
layout=Layout(width='200px'),
readout_format='.1f',
)
slider_r.observe(update_r,names='value')
slider_a = FloatSlider(
value=rab[1],
min=ab_range[0],
max=ab_range[1],
continuous_update=True,
orientation='horizontal',
indent=True,
layout=Layout(width='200px'),
readout_format='.1f',
)
slider_a.observe(update_a,names='value')
slider_b = FloatSlider(
value=rab[2],
min=ab_range[0],
max=ab_range[1],
continuous_update=True,
orientation='horizontal',
indent=True,
layout=Layout(width='200px'),
readout_format='.1f',
)
slider_b.observe(update_b,names='value')
# widgets.Text(
# value='Hello World',
# placeholder='Type something',
# description='String:',
# disabled=False
# )
# Controls box
controls_vbox = VBox([
Label(
value = r"Shape Factor $$\,\,r$$",
style={'font_weight': 'bold'},
layout=Layout(width='200px')
),
slider_r,
Label(
value = r"Tilt Limit $$\,\,\alpha$$",
style={'font_weight': 'bold'},
layout=Layout(width='200px')
),
slider_a,
Label(
value = r"Tilt Limit $$\,\,\beta$$",
style={'font_weight': 'bold'},
layout=Layout(width='200px')
),
slider_b,
],layout=Layout(width='220px'))
# Assemble widget
visualization_layout = Layout(
display='flex',
flex_flow='row',
align_items='center',
width='680px'
)
display(
HBox(
[
fig.canvas,
controls_vbox
],
layout=visualization_layout
)
)
HBox(children=(Canvas(footer_visible=False, header_visible=False, layout=Layout(width='470px'), resizable=Fals…