Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

set_view! doesn't force an update #12

Closed
timholy opened this issue Jun 13, 2024 · 3 comments
Closed

set_view! doesn't force an update #12

timholy opened this issue Jun 13, 2024 · 3 comments

Comments

@timholy
Copy link
Member

timholy commented Jun 13, 2024

I'm sure I'm making a complete mess of this, but I'm trying to do a plot in which:

  • initially, I fly from a more distant point to a closer, central point
  • then I start spinning around the scene
  • I iterate through a list-of-lists of locations, revealing all the locations iteratively. An even set is appearing while an odd set is vanishing.

This makes use of FlyThroughPaths, ProtPlot, and some other machinery. Here's a slightly stripped-down version of the script:

using GLMakie
using FlyThroughPaths
using ProgressMeter

if !isdefined(@__MODULE__, :familyxyz)  # this creates a dataframe
    include("analyze_binding_residue_kinds.jl")
end

## Animated plot of residue locations by kind
pdbname = joinpath(v1r.parentdir, opsdname*"_aligned.pdb")
fig = Figure(size=(800, 800));
ax = ribbon_scene(pdbname; colors=[fill(RGBA(ribboncolor, 0.3), length(opsd))], backgroundcolor=:white)
mgrid = range(-30, stop=30, length=2)
zgrid = fill(15.0, 2, 2)
cgrid = fill(RGBA(0, 0, 0, 0.1), 2, 2)
surface!(ax, mgrid, mgrid, zgrid, color=cgrid, transparency=true)
surface!(ax, mgrid, mgrid, -zgrid, color=cgrid, transparency=true)
# Use an Observable for transparency so we can control it during animation.
alpha_even, alpha_odd = Observable(1.0), Observable(0.0)
xpos_even, ypos_even, zpos_even = Observable(Float64[]), Observable(Float64[]), Observable(Float64[])
xpos_odd, ypos_odd, zpos_odd = Observable(Float64[]), Observable(Float64[]), Observable(Float64[])
markersize=10
scatter!(ax, xpos_even, ypos_even, zpos_even; color=familycolordict["V1R"], markersize, alpha=alpha_even)
scatter!(ax, xpos_odd, ypos_odd, zpos_odd; color=familycolordict["V1R"], markersize, alpha=alpha_odd)
gdf = groupby(familyxyz, [:family, :orclass, :msacode])
vgdf = filter(collect(pairs(gdf))) do (k, v)
    k.family == "V1R"
end

# Fly in to the midpoint
r = 75
θ = -0.32175
n = 200= 2π / n
tland = 5
tdur = 4
path = Path(ViewState(eyeposition=Vec3f(120, -40, 35), lookat=zero(Vec3f), upvector=Vec3f(0, 0, 1), fov=45))
path *= ConstrainedMove(tland, ViewState(eyeposition=r*Vec3f(cos(θ), sin(θ), 0)))
idxlast = 0
prog = Progress(n; desc="Recording movie...")
display(fig)
# record(fig, "positive_residue_locations.mp4", LinRange(0, tland + tdur*20, n); framerate=10) do t
foreach(LinRange(0, tland + tdur*20, n)) do t
    global idxlast

    cview = t <= tland ? path(t) : ViewState(eyeposition=r*Vec3f(cos+ (t-tland)*dθ), sin+ (t-tland)*dθ), 0), lookat=zero(Vec3f), upvector=Vec3f(0, 0, 1), fov=45)
    if t > tland
        tnow = t - tland
        ti = round(Int, tnow / tdur)
        if ti >= idxlast
            idxlast += 1
            nextname, nextreceptor = vgdf[idxlast]
            if idxlast % 2 == 0
                empty!(xpos_even[]); empty!(ypos_even[]); empty!(zpos_even[])
                for row in eachrow(nextreceptor)
                    push!(xpos_even.val, row.x)
                    push!(ypos_even.val, row.y)
                    push!(zpos_even.val, row.z)
                end
                notify(xpos_even)
            else
                empty!(xpos_odd[]); empty!(ypos_odd[]); empty!(zpos_odd[])
                for row in eachrow(nextreceptor)
                    push!(xpos_odd.val, row.x)
                    push!(ypos_odd.val, row.y)
                    push!(zpos_odd.val, row.z)
                end
                notify(xpos_odd)
            end
        end
    end
    next!(prog)
    set_view!(ax, cview)
    alpha_even.val = (cos* t / tdur) + 1)/2
    alpha_odd[]  = (sin* t / tdur) + 1)/2
    sleep(0.01)
end
println("done")

While this is executing I just get a blank screen. It stays that way at the end. But if at the REPL I do

julia> set_view!(ax, capture_view(ax))

then I get

image

which is basically what I want. (The purple dots are the locations I'm showing in the even/odd lists.)

The record line also records a blank movie.

@asinghvi17
Copy link
Collaborator

You need to run Makie.update_state_before_display!(fig) before taking the initial ViewState - that instantiates all limits. It's an optimization on the Makie end to avoid loops and extra computation.

@timholy
Copy link
Member Author

timholy commented Jun 13, 2024

Thanks! That didn't seem to be enough, somehow, but I found that

fig = Figure(size=(800, 800), backgroundcolor=:white);
ax = LScene(fig[1, 1]; show_axis=false)
ribbon!(ax, pdbname; colors=[fill(RGBA(ribboncolor, 0.2), length(opsd))], backgroundcolor=:white)
display(fig)     # this is critical

seems to work. Then I can do the scatter! plot and all the fancy view/transparency stuff and it updates nicely.

I presume this is more of a Makie nuance than anything this package needs to fix, so I'll close.

@timholy timholy closed this as completed Jun 13, 2024
@asinghvi17
Copy link
Collaborator

Huh, that's surprising. Probably update_state_before_display is not implemented properly for LScene - that will have to be fixed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants