This notebook reproduces Fig. 8 in the paper, which shows the the frequency change $\Delta f$ as a function of particle separation for a particle located above the centre of the nanodisc (x = 0 nm, y = 0 nm) as well as for an off-centre particle (x = 0 nm, y = 20 nm).
In [1]:
import matplotlib.lines as mlines
import matplotlib.pyplot as plt
import pandas as pd
from style_helpers import style_cycle
%matplotlib inline
plt.style.use('style_sheets/custom_style.mplstyle')
Read the data frame containing the eigenmode data and filter out the parameter values relevant for this plot.
In [2]:
df = pd.read_csv('../data/eigenmode_info_data_frame.csv')
df = df.query('(has_particle == True) & (d_particle == 20) & (Ms_particle == 1e6) & (Hz == 8e4)')
df = df.sort_values('d')
Define a few helper functions which are used to produce the plot below.
In [3]:
def create_figure_and_inset():
"""
Create matplotlib figure with two axes ax1, ax2,
where ax2 is an inset inside ax1.
Returns the figure `fig`, as well as ax1 and ax2.
"""
fig, ax1 = plt.subplots(figsize=(8, 6))
ax1.spines['right'].set_visible(False)
ax1.spines['top'].set_visible(False)
ax1.xaxis.set_ticks_position('bottom')
ax1.yaxis.set_ticks_position('left')
ax2 = fig.add_axes([0.48, 0.48, 0.4, 0.4], frameon=True)
ax2.spines['right'].set_visible(False)
ax2.spines['top'].set_visible(False)
ax2.xaxis.set_ticks_position('bottom')
ax2.yaxis.set_ticks_position('left')
ax2.set_axis_bgcolor('none')
return fig, ax1, ax2
In [4]:
def plot_freq_change_vs_particle_distance_for_mode(ax, N, df, linestyle='o-', **mpl_kwargs):
"""
Plot a single curve showing `delta_f` vs. particle separation `d`
for the eigenmode `N`.
"""
df_filtered = df.query('N == {N}'.format(N=N)).sort_values('d')
d_vals = df_filtered['d']
freq_diffs = df_filtered['freq_diff'] * 1e3 # frequency change in MHz, not GHz
ax.plot(d_vals, freq_diffs, linestyle, label='N={N}'.format(N=N), **mpl_kwargs)
In [5]:
def plot_frequency_change_vs_particle_distance(
ax, x, y, ann, Nvals, ylim=None, linestyle='-',
use_custom_style=True, xticks=None, yticks=None,
xlabel='Particle separation d (nm)',
ylabel=r'Frequency change $\;\Delta f$ (MHz)',
labelfontsize=18, tickfontsize=16,
ann_xy=(0.125, 0.95), ann_fontsize=18,
show_legend=True, show_zero_freq_line=True):
"""
Plot curves for all eigenmodes (i.e. all values of `N`)
showing the dependence of `delta_f` on particle separation `d`.
The arguments `x` and `y` represent the x/y-coordinates of the
nanoparticle.
"""
df_filtered = df.query('x == {x} and y == {y}'.format(x=x, y=y))
Nmin = min(Nvals)
Nmax = max(Nvals)
for N, style_kwargs in reversed(list(zip(range(Nmin, Nmax+1), style_cycle))):
if N not in Nvals:
continue
plot_freq_change_vs_particle_distance_for_mode(ax, N, df_filtered, linestyle=linestyle, **style_kwargs)
if show_zero_freq_line:
ax.plot([0, 90], [0, 0], '--k', linewidth=2)
if xticks:
ax.set_xticks(xticks)
if yticks:
ax.set_yticks(yticks)
plt.setp(ax.get_xticklabels(), fontsize=tickfontsize)
plt.setp(ax.get_yticklabels(), fontsize=tickfontsize)
ax.annotate(ann,
xy=ann_xy, xycoords='axes fraction',
xytext=(0, 0), textcoords='offset points',
#arrowprops=dict(facecolor='black', shrink=0.05),
horizontalalignment='left', verticalalignment='center',
fontsize=ann_fontsize,
)
ax.set_xlabel(xlabel, fontsize=labelfontsize)
ax.set_ylabel(ylabel, fontsize=labelfontsize)
if show_legend:
ax.legend(numpoints=1, loc='best')
ax.set_xlim(0, 90)
ax.set_ylim(ylim)
In [6]:
# Define keyword arguments for the inset, which will be
# passed to the plotting function below.
kwargs_for_inset = {
'Nvals': [1, 3, 4],
'show_legend': False,
'xlabel': 'd (nm)',
'ylabel': r'$\Delta f$ (MHz)',
'show_zero_freq_line': False,
'ylim': (2, 600),
'labelfontsize': 14,
'tickfontsize': 13,
'ann_fontsize': 14,
'ann_xy': (0.2, 0.9),
'xticks': [0, 15, 30, 45, 60, 75, 90],
'yticks': [0, 200, 400, 600],
}
Produce the plot for Fig. 8.
In [7]:
fig, ax1, ax2 = create_figure_and_inset()
plot_frequency_change_vs_particle_distance(x=0, y=0, ann='centred\nparticle', ax=ax1, Nvals=[1, 2, 3, 4, 5])
plot_frequency_change_vs_particle_distance(x=0, y=20, ann='off-centre\nparticle', ax=ax2, **kwargs_for_inset)