# Plotting Atomic Orbitals with Makie

**URL:** https://discourse.julialang.org/t/plotting-atomic-orbitals-with-makie/71032
**Category:** General Usage
**Tags:** plotting, chemistry, makie
**Created:** [November 5, 2021, 11:12pm UTC](https://discourse.julialang.org/t/plotting-atomic-orbitals-with-makie/71032 "2021-11-05T23:12:27Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Aroeira](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aroeira/32/22593_2.png) [@Aroeira](https://discourse.julialang.org/u/Aroeira)
#### Post date: [November 5, 2021, 11:12pm UTC](https://discourse.julialang.org/t/plotting-atomic-orbitals-with-makie/71032/1 "2021-11-05T23:12:28Z")

</div>

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

```julia
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)

 ![ao_plot](https://global.discourse-cdn.com/julialang/original/3X/7/b/7b91834b8679a4611a9599d57dad48a161752344.png)

I am happy with the result, but there are several points where it could improve:

1. 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.
2. The show axis toggle does not work, did I get my events/observables right?
3. 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?
4. 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?  
 ![ao2](https://global.discourse-cdn.com/julialang/original/3X/8/6/8642c011d6128bf75437b531d6746fcca14e22ea.png)  
_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!

---

<div class="post-metadata">

### Author: ![ffreyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffreyer/32/21569_2.png) [@ffreyer](https://discourse.julialang.org/u/ffreyer)
#### Post date: [November 6, 2021, 7:54am UTC](https://discourse.julialang.org/t/plotting-atomic-orbitals-with-makie/71032/2 "2021-11-06T07:54:40Z")

</div>

1. You’re fine. At the moment Makie just has something like `if show_axis[]; add_axis!()`. You’d need something like

```julia
on(toggles[1].active) do visible
    ax.scene.plots[1].plots[1].visible[] = visible
    ax.scene.plots[1].plots[2].visible[] = visible
end

```

and have `show_axis = true` to toggle them.

1. `img = Makie.colorbuffer(fig.scene.current_screens[1])` works without closing the screen in GLMakie. (Edit: The inline display in vscode doesn’t work for me with this, but the image seems correct.)
2. That should be working in the latest release. (But only for iso and 3d contours)

---

<div class="post-metadata">

### Author: ![AshtonSBradley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashtonsbradley/32/11140_2.png) [@AshtonSBradley](https://discourse.julialang.org/u/AshtonSBradley)
#### Post date: [November 6, 2021, 5:01pm UTC](https://discourse.julialang.org/t/plotting-atomic-orbitals-with-makie/71032/3 "2021-11-06T17:01:49Z")

</div>

There is also discussion here about object stacking

> [@Makie isosurface transparency?](https://discourse.julialang.org/t/makie-isosurface-transparency/65214/12):
>
> Ok, getting closer. Still puzzling: I make a torus geometry. Why isn’t the full torus visible even though there is an alpha? It seems that the alpha is applied to another surface (dual ellipsoid case above), but not to different parts of the same surface. We should be able to see the core of the torus, and the back surface: using GLMakie using ColorSchemes cmap3 = get(colorschemes[:plasma], LinRange(0,1,100)) cmap4 = [(cmap3[i],0.65) for i in 1:100] ξ = -40:1:40 c = 20 a = 15 torus = [((h…

---

<div class="post-metadata">

### Author: ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)
#### Post date: [November 7, 2021, 6:59am UTC](https://discourse.julialang.org/t/plotting-atomic-orbitals-with-makie/71032/4 "2021-11-07T06:59:43Z")

</div>

> [@Aroeira](#):
>
> 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.

What about the organization do you not like at the moment? You’re not necessarily using the easiest syntax, but there’s also nothing inherently wrong with it. But for example, I wouldn’t put the axis over so many rows and columns, to match with the menu. It’s easier to nest GridLayouts so they’re independent (why should the rows of the gui part have anything to do with the size of the plot).

Here’s an example:

```julia
f = Figure()

LScene(f[1, 1])
scatter!(randn(100, 3))
gui_grid = f[1, 2] = GridLayout(width = 200, tellheight = false)

Label(gui_grid[1, 1][1, 1], "Label")
Menu(gui_grid[1, 1][1, 2])

ls = labelslider!(f, "slider", 1:10)
gui_grid[2, 1] = ls.layout

togglegrid = gui_grid[3, 1] = GridLayout(tellwidth = false)
Toggle(togglegrid[1, 1])
Label(togglegrid[1, 2], "show axis")

Button(gui_grid[4, 1], label = "save", tellwidth = false)

f

```

 ![grafik](https://global.discourse-cdn.com/julialang/original/3X/6/c/6c35b8e56cd9eef8d75297a620cf95be0c7802c5.jpeg)

---

<div class="post-metadata">

### Author: ![Aroeira](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aroeira/32/22593_2.png) [@Aroeira](https://discourse.julialang.org/u/Aroeira)
#### Post date: [November 8, 2021, 12:09am UTC](https://discourse.julialang.org/t/plotting-atomic-orbitals-with-makie/71032/5 "2021-11-08T00:09:03Z")

</div>

Thank you, this type of organization is what I was looking for. I did not know how to nest things.
