Hello, I am trying to write a function to produce an interactive plot for Atomic Orbitals using Makie.jl.
The ultimate goal is to plot molecular orbitals, but if I can do atomic ones the extension must be trivial.
First of all, I am using a structure called BasisFunction
(the variable bf
in the code below) along with a function that can take this struct and compute the value of this orbital for a position (x,y,z).
Currently, the code looks like this
function isoplot(bf, min, max, N)
fig = Figure()
lscene = LScene(fig[1:5,1:4])
# Menus
menu = Menu(fig, options = collect(-bf.l:1:bf.l), tellwidth = false)
fig[1,5] = grid!(
hcat(Label(fig, L"m_l", width = nothing, textsize = 30.0f0), menu),
tellheight = false,
width = 300
)
# Sliders
lsgrid = labelslidergrid!(
fig,
["Isovalue"],
[0:0.01:0.5],
formats = [x -> "$x"],
tellheight = false
)
fig[2,5] = lsgrid.layout
# Toggles
toggles = [
Toggle(fig, active = true)
]
tlabels = [
Label(fig, "Show axis")
]
fig[3,5] = grid!(hcat(toggles, tlabels), tellheight = false)
# Buttons
fig[4, 5] = buttongrid = GridLayout(tellwidth = false)
button = buttongrid[1,1] =[Button(fig, label = "Save")]
on(button[1].clicks) do n
lscene.scene.center = false
save("atomicorbital.png", lscene.scene)
end
set_close_to!(lsgrid.sliders[1], 0.48)
menu.selection[] = 0
iv = lsgrid.sliders[1].value
negiv = lift(iv) do x
-x
end
r = LinRange(min, max, N)
wf = lift(menu.selection) do ml
[basis_function_eval(bf, x, y, z, Integer(ml[])) for x = r, y = r, z = r]
end
volume!(r, r, r, wf, algorithm = :iso, isorange = 0.01,
isovalue = iv, show_axis=toggles[1].active, colormap = colormap("reds"), colorrange = (0, 0.5))
volume!(r, r, r, wf, algorithm = :iso, isorange = 0.01,
isovalue = negiv, show_axis=toggles[1].active, colormap = colormap("blues"), colorrange = (0, -0.5))
return fig
end
Plotting the function is somewhat straightforward, most of this mess is trying to set up layoutables. The current result looks like for Hygroen (1p function from cc-pvdz basis)
I am happy with the result, but there are several points where it could improve:
- The overall organization: is there an easier way to have several widgets on a single column? I did not find many examples mixing menus, sliders, etc.
- The show axis toggle does not work, did I get my events/observables right?
- The save button works, but it closes the window. It would be great if I could have an input for the file path, but maybe that can go in the function call. Is there a way to change the dpi, just for saving?
- The main problem right now is the overlap of the two plots. In order to have both negative and positive parts showing, I used
volume!
twice. It looks fine, but the negative plot is always on top of the positive, no matter the perspective. Can that be fixed?
In this picture, the positive (red) part of the function is closer to the came, still the blue one is shown on top of it.
I appreciate any comments, suggestions or other examples you could send me.
Thank you!