migrated to bokeh
This commit is contained in:
parent
3e24987f05
commit
e6a841e09a
@ -1,9 +1,13 @@
|
|||||||
<head>
|
<head>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
|
||||||
|
<link href=”https://cdn.pydata.org/bokeh/release/bokeh-3.7.1.min.css" rel=”stylesheet” type=”text/css”>
|
||||||
|
<link href=”https://cdn.pydata.org/bokeh/release/bokeh-widgets-3.7.1.min.css" rel=”stylesheet” type=”text/css”>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
<div class="center">
|
<div class="center">
|
||||||
|
<h1>Isotopes</h1>
|
||||||
<table class="table w-auto table-responsive-sm table-striped table-hover table-bordered">
|
<table class="table w-auto table-responsive-sm table-striped table-hover table-bordered">
|
||||||
<caption>
|
<caption>
|
||||||
Table downloaded from <a href="https://easyspin.org/documentation/isotopetable.html">easyspin.org</a>
|
Table downloaded from <a href="https://easyspin.org/documentation/isotopetable.html">easyspin.org</a>
|
||||||
@ -29,17 +33,26 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
{{ div| safe }}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<img src="data:image/png;base64, {{ figure }}" alt="somealt" />
|
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-3.7.1.min.js"></script>
|
||||||
|
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.7.1.min.js"></script>
|
||||||
|
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-tables-3.7.1.min.js"></script>
|
||||||
|
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-api-3.7.1.min.js"></script>
|
||||||
|
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-mathjax-3.7.1.min.js"></script>
|
||||||
|
|
||||||
|
{{ script| safe }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<a href="{% url 'home' %}">Go Back</a>
|
<a href="{% url 'home' %}">Go Back</a>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</body>
|
||||||
<style>
|
<style>
|
||||||
.center {
|
.center {
|
||||||
margin: auto;
|
margin: auto;
|
||||||
@ -55,6 +68,8 @@
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.table-striped {--bs-table-striped-bg: rgba(213, 217, 255, 0.7);}
|
.table-striped {
|
||||||
|
--bs-table-striped-bg: rgba(213, 217, 255, 0.7);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -4,20 +4,18 @@ import base64
|
|||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
import re
|
import re
|
||||||
import numpy as np
|
|
||||||
import matplotlib
|
|
||||||
from setuptools.command.rotate import rotate
|
|
||||||
|
|
||||||
matplotlib.use('Agg')
|
from bokeh.plotting import figure as bokehfig
|
||||||
from matplotlib.patches import Wedge, FancyArrowPatch
|
from bokeh.embed import components
|
||||||
import matplotlib.pyplot as plt
|
from bokeh.models import Label, Node, MathML
|
||||||
|
|
||||||
|
|
||||||
from isotopapp.models import Isotope
|
from isotopapp.models import Isotope
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
|
|
||||||
def home(request):
|
def home(request):
|
||||||
isotopes = [i for i in Isotope.objects.all() if (i.gamma != 0 or i.stable)]
|
isotopes = [i for i in Isotope.objects.all() if (i.gamma != 0 or i.stable)]
|
||||||
return render(request, 'home.html', {'isotopes': [[f"{i.n_nucleons}{i.symbol}", mark_safe(f"<sup>{i.n_nucleons}</sup>{i.symbol}")] for i in isotopes]})
|
return render(request, 'home.html', {'isotopes': [[f"{i.n_nucleons}{i.symbol}", mark_safe(f"<sup>{i.n_nucleons}</sup>{i.symbol}")] for i in isotopes],})
|
||||||
|
|
||||||
def extract_isotope_parts(isotope_str):
|
def extract_isotope_parts(isotope_str):
|
||||||
"""Extracts the number and element from an isotope string (e.g., '23Na')."""
|
"""Extracts the number and element from an isotope string (e.g., '23Na')."""
|
||||||
@ -49,7 +47,9 @@ def result(request):
|
|||||||
|
|
||||||
field_T = freq / isotope1.gamma
|
field_T = freq / isotope1.gamma
|
||||||
|
|
||||||
figure=None
|
script = None
|
||||||
|
div = None
|
||||||
|
|
||||||
print(request.GET)
|
print(request.GET)
|
||||||
if request.GET.get('range_search') == "":
|
if request.GET.get('range_search') == "":
|
||||||
close_isotopes = [isotope_info(isotope1, field_T)]
|
close_isotopes = [isotope_info(isotope1, field_T)]
|
||||||
@ -65,24 +65,14 @@ def result(request):
|
|||||||
ans = sorted(close_isotopes, key=lambda x: -float(x[3]))
|
ans = sorted(close_isotopes, key=lambda x: -float(x[3]))
|
||||||
|
|
||||||
elif request.GET.get('gradient_search') == "":
|
elif request.GET.get('gradient_search') == "":
|
||||||
fig, ax = plt.subplots(1, 1)
|
|
||||||
theta1, theta2 = 0, 360
|
|
||||||
radius = 2.5
|
|
||||||
center = (0, 0)
|
|
||||||
w = Wedge(center, radius, theta1, theta2, fc='#D5D9FFB2', edgecolor='black')
|
|
||||||
w_upper = Wedge((0,2.5), radius, theta1, theta2, fc='#D5D9FF42', edgecolor='black')
|
|
||||||
w_lower = Wedge((0,-2.5), radius, theta1, theta2, fc='#D5D9FF42', edgecolor='black')
|
|
||||||
|
|
||||||
ax.set_xlim([-5.5, 5.5])
|
|
||||||
ax.set_ylim([-5.5, 5.5])
|
|
||||||
ax.grid(True)
|
|
||||||
|
|
||||||
ax.add_patch(w_upper)
|
|
||||||
ax.add_patch(w_lower)
|
|
||||||
ax.add_patch(w)
|
|
||||||
|
|
||||||
sample_diameter = 5e-3
|
sample_diameter = 5e-3
|
||||||
gradient = float(request.GET.get('gradient'))
|
gradient = float(request.GET.get('gradient'))
|
||||||
|
# create a plot (bokeh)
|
||||||
|
plot = bokehfig(outer_width=400, outer_height=400, match_aspect=True)
|
||||||
|
plot.ellipse(x=[0], y=[0], width=5, height=5, color="#D5D9FF", alpha=0.8, line_width=1, line_color="black")
|
||||||
|
plot.ellipse(x=[0], y= [2.5], width=5, height=5, color="#D5D9FF", alpha=0.4, line_width=1, line_color="black")
|
||||||
|
plot.ellipse(x=[0], y=[-2.5], width=5, height=5, color="#D5D9FF", alpha=0.4, line_width=1, line_color="black")
|
||||||
|
|
||||||
|
|
||||||
close_isotopes = []
|
close_isotopes = []
|
||||||
for isotope in Isotope.objects.all():
|
for isotope in Isotope.objects.all():
|
||||||
@ -93,22 +83,36 @@ def result(request):
|
|||||||
i_info = isotope_info(isotope, field_T)
|
i_info = isotope_info(isotope, field_T)
|
||||||
#i_info[3] = f"{z*1e3:.1f} mm"
|
#i_info[3] = f"{z*1e3:.1f} mm"
|
||||||
close_isotopes.append(i_info)
|
close_isotopes.append(i_info)
|
||||||
|
mathml = f"""
|
||||||
|
<math>
|
||||||
|
<msup>
|
||||||
|
{isotope.n_nucleons}
|
||||||
|
</msup>
|
||||||
|
{isotope.symbol}
|
||||||
|
</math>
|
||||||
|
"""
|
||||||
|
plot.rect(x=[0], y=[z*1e3], width=5, height=0.2, color="black", alpha=0.6)
|
||||||
|
label = Label(x=2.6, y=z*1e3, text=f"{isotope.n_nucleons}{isotope.symbol}", text_baseline="middle", text_align="left", text_font_size="16pt")
|
||||||
|
#label = Label(x=2.6, y=z*1e3, text=MathML(mathml), text_baseline="middle", text_align="left", text_font_size="16pt")
|
||||||
|
plot.add_layout(label)
|
||||||
|
|
||||||
arr = FancyArrowPatch((-2.5,z*1e3), (2.5, z*1e3),
|
frame_left = Node(target="frame", symbol="left", offset=5)
|
||||||
arrowstyle='-', mutation_scale=20, linewidth=2)
|
frame_bottom = Node(target="frame", symbol="bottom", offset=-5)
|
||||||
ax.add_patch(arr)
|
citation = Label(
|
||||||
ax.annotate(f"{isotope.n_nucleons}{isotope.symbol}", (1.1, 0), xycoords=arr, ha='left', va='center',fontsize=8)
|
x=frame_left,
|
||||||
ax.annotate(f"{isotope1.n_nucleons}{isotope1.symbol}: {freq:.1f}MHz\ng={gradient:.1f}T/m",
|
y=frame_bottom,
|
||||||
(0.91, -0.45), xycoords=w,
|
anchor="bottom_left",
|
||||||
ha='left', va='center',fontsize=11)
|
#text=MathML(text=f"<math><msup>{isotope1.n_nucleons}</msup>{isotope1.symbol}: {freq:.1f} MHz\ng={gradient:.1f} T/m\n5 mm sample dia.</math>"),
|
||||||
|
text=f"{isotope1.n_nucleons}{isotope1.symbol}: {freq:.1f} MHz\ng={gradient:.1f} T/m\n5 mm sample dia.",
|
||||||
|
#text=MathML("<math>tewt</math>"),
|
||||||
|
padding=10,
|
||||||
|
border_radius=5,
|
||||||
|
border_line_color="black", background_fill_color="white",
|
||||||
|
)
|
||||||
|
plot.add_layout(citation)
|
||||||
|
|
||||||
ax.set_aspect('equal')
|
# boke plot
|
||||||
ax.set_ylabel('z (mm)')
|
script, div = components(plot)
|
||||||
|
|
||||||
buf = BytesIO()
|
|
||||||
plt.savefig(buf, format='png', dpi=120)
|
|
||||||
figure = base64.b64encode(buf.getvalue()).decode('utf-8').replace('\n', '')
|
|
||||||
buf.close()
|
|
||||||
ans = sorted(close_isotopes, key=lambda x: float(x[3]))
|
ans = sorted(close_isotopes, key=lambda x: float(x[3]))
|
||||||
|
|
||||||
elif request.GET.get('transform') == "":
|
elif request.GET.get('transform') == "":
|
||||||
@ -118,4 +122,4 @@ def result(request):
|
|||||||
ans = [isotope_info(isotope2, field_T)]
|
ans = [isotope_info(isotope2, field_T)]
|
||||||
else:
|
else:
|
||||||
ans = []
|
ans = []
|
||||||
return render(request, 'result.html', {'ans': ans, 'figure': figure})
|
return render(request, 'result.html', {'ans': ans, 'script': script, 'div': div})
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
Django==5.1.6
|
Django==5.1.6
|
||||||
matplotlib==3.10.1
|
#matplotlib==3.10.1
|
||||||
|
bokeh==3.7.1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user