From 32f09a06b39f574f5764e513c79f9071d34fb9a9 Mon Sep 17 00:00:00 2001
From: Bowy La Riviere <b.m.lariviere@student.tudelft.nl>
Date: Mon, 7 Dec 2020 16:46:51 +0000
Subject: [PATCH] Converted the slider plot to a pyplot format

---
 src/1_einstein_model.md | 181 +++++++++++++++++++++++++++-------------
 1 file changed, 123 insertions(+), 58 deletions(-)

diff --git a/src/1_einstein_model.md b/src/1_einstein_model.md
index 9de9f29f..3774d6a9 100644
--- a/src/1_einstein_model.md
+++ b/src/1_einstein_model.md
@@ -306,72 +306,137 @@ This means that there is not enough thermal energy to excite the harmonic oscill
 ```python
 # Defining variables
 y_line = [0, 0.92];
-x_max = 2.5
-temps = np.linspace(0.01, x_max, 750)
+T_max = 3
+temps = np.linspace(0.01, T_max, 750)
+N_values = 20
+T_E_max = 2
+l_width = 1.5
+N_active = 9
 
+# Create figure
+fig = go.Figure()
+
+# Heat capacity
 def c_einstein(T, T_E):
     x = T_E / T
     return 3 * x**2 * np.exp(x) / (np.exp(x) - 1)**2
 
-def einstein_temp_plot(T_E):
-    # Creating plot
-    fig, ax = pyplot.subplots(figsize = (12, 9))
-    pyplot.hlines([1], 0, x_max, linestyles = 'dashed', label = r'Classical')
-    ax.plot(temps, c_einstein(temps, T_E)/3, '-', label = r'Einstein model')
-    ax.plot([T_E, T_E], y_line, 'r--')
-    ax.fill_between(temps, c_einstein(temps, T_E)/3, 1, alpha = 0.5)
-    ax.set_title('Heat capacity of the Einstein model and the equipartition theorem')
-    ax.set_ylim(bottom = 0, top = 1.2)
-    ax.set_xlabel('$T$')
-    ax.set_ylabel(r'$C$')
-    ax.set_xticks([0])
-    ax.set_xlim((0, x_max))
-    ax.set_xticklabels(['$0$'])
-    ax.set_yticks([1])
-    ax.set_yticklabels(['$k_B$'])
-    ax.text(T_E+0.05, 0.5, r'$T= T_E= \hbar \omega_0/k_{\rm B}$', ha='left', color='r')
-    ax.legend(loc = 'lower right')
-    pyplot.show()
-    return()
+# Add traces, one for each slider step
+for T_E in np.linspace(0.1, T_E_max, N_values):
+    fig.add_trace(
+        go.Scatter(
+            visible = False,
+            x = [0, T_max],
+            y = [1, 1],
+            mode = 'lines',
+            line_color = 'lightblue',
+            line_dash = 'dot',
+            name = "Equipartition theorem",
+        ))
+    fig.add_trace(
+        go.Scatter(
+            visible = False,
+            x = temps,
+            y = c_einstein(temps, T_E)/3,
+            mode = 'lines',
+            line_color = 'blue',
+            line_dash = 'dot',
+            name = 'Einstein model',
+            fill = 'tonextx',
+            fillcolor = 'lightblue'
+        ))
+    fig.add_trace(
+        go.Scatter(
+            visible = False,
+            x = [T_E, T_E],
+            y = y_line,
+            mode = 'lines',
+            line_color = 'red',
+            line_dash = 'dot',
+            name =  r'$T = T_E = \hbar \omega/k_B$'
+        ))
+
+    
+# Initial starting image
+N_trace = int(len(fig.data)/N_values) # Number of traces added per step
+for j in range(N_trace):
+    fig.data[N_active*N_trace+j].visible = True
+
+    
+# Creation of the aditional images
+steps = []
+for i in range(int(len(fig.data)/N_trace)):
+    step = dict(
+        method = "restyle",
+        args = [{"visible": [False] * len(fig.data)}],
+        value = str(0.1*(i+1))
+    )
+    for j in range(N_trace):
+        step["args"][0]["visible"][N_trace*i+j] = True  # Toggle i'th trace to "visible"
+    steps.append(step)
 
 # Creating the slider
-layout_slider = Layout(width = '725px', height = '20px')
-float_slider = FloatSlider(
-    value = 1, 
-    min = 0.1, max = 2, step = 0.05,
-    description = r'$T_E$',
-    continuous_update = True,
-    orientation = 'horizontal',
-    readout_format = '.1f',
-    layout = layout_slider)
-
-# Creating the plot
-control = interact(einstein_temp_plot, T_E = float_slider)
-```
-
-The horizontal dashed line is the classical value, $k_{\rm B}$. The shaded area is the difference between the classical value $k_B$ and the value predicted by the Einstein model. Integrating over the shaded area yields $\frac{1}{2}\hbar\omega_0$, which is the zero-point energy of the oscillator, which cannot be extracted from the system. The vertical dashed line depicts the Einstein temperature $T_E$, at which the heat capacity $C \approx 0.92 k_B$.
-
-The calculations above were done for a single harmonic oscillator. In order to obtain the heat capacity of a full material, we would have to multiply $C$ (or $\langle E \rangle$) by $3N$. The $N$ comes from the number of harmonic oscilators in the solid and the factor 3 originates from the dimensionality of the system. 
-??? note "1D versus 3D harmonic oscillator"
+sliders = [dict(
+    tickcolor = 'White',
+    font_color = 'White',
+    currentvalue_font_color = 'Black',
+    active = N_active,
+    name = r'Einstein temperature',
+    font_size = 16,
+    currentvalue = {"prefix": r"Einstein temperature:"},
+    pad = {"t": 50},
+    steps = steps,
+)]
+
+# Updating the images for each step
+fig.update_layout(
+    sliders = sliders,
+    showlegend = True,
+    plot_bgcolor = 'rgb(254, 254, 254)',
+    width = 1000,
+    height = 667,
+    xaxis = dict(
+        range=[0, T_max],
+        visible = True,
+        showticklabels = True,
+        showline = True,
+        linewidth = l_width, 
+        linecolor = 'black',
+        gridcolor = 'white',
+        tickfont = dict(size = 16)),
+    yaxis = dict(
+        range = [0, 1.1],
+        visible = True,
+        showticklabels = True,
+        showline = True,
+        linewidth = l_width, 
+        linecolor = 'black',
+        gridcolor = 'white',
+        tickfont = dict(size = 16)),
+    title = {'text': r'Heat capacity of the Einstein model and the equipartition theorem',
+        'y':0.9,
+        'x':0.45,
+        'xanchor': 'center',
+        'yanchor': 'top'},
+    xaxis_title = r'$T$',
+    yaxis_title = r'$C/K_B$',
+    legend = dict(
+    yanchor="bottom",
+    y = 0.1,
+    xanchor = "right",
+    x = 0.99,
+    bgcolor = "white",
+    bordercolor = "Grey",
+    borderwidth = 1)
+)  
+      
+# Edit slider labels and adding text next to the horizontal bar indicating T_E
+for i in range(N_values):
+    fig['layout']['sliders'][0]['steps'][i]['label'] = ' ' + str(T_E_max*i/N_values + T_E_max/N_values)
+                                                          
+# Showing the figure
+fig.show();
 
-        One 3D (quantum) harmonic oscillator is equivalent to three independent 1D (quantum) harmonic oscillators. Therefore, we can simply multiply by a factor of 3.
-
-The plot below shows a fit of the Einstein model to the experimental data for the heat capacity of diamond.
-
-```python
-fit = curve_fit(c_einstein, T, c, 1000)
-T_E = fit[0][0]
-delta_T_E = np.sqrt(fit[1][0, 0])
-
-fig, ax = pyplot.subplots()
-ax.scatter(T, c, label = r'Experimental value')
-
-temps = np.linspace(10, T[-1], 100)
-ax.plot(temps, c_einstein(temps, T_E), label = r'Einstein model');
-ax.set_title(r'Emperical and predicted heat capacity of diamond')
-ax.set_xlabel('$T[K]$')
-ax.set_ylabel('$C/k_B$')
-ax.set_ylim((0, 3));
 ```
 
 Although the Einstein model fits the experimental data quite well, it still deviates from the experimental data in the low temperature regime.
-- 
GitLab