有效地使用 Plots.jl 对子图进行动画处理



我正在尝试使用 Plots.jl 和 GR 后端在 Julia 中创建具有三个子图(一个表面、两个热图(的动画。到目前为止,我的代码中最慢的部分是这些图的生成,所以我正在尝试找到最有效的方法来做到这一点。

我尝试在动画循环中重新调用绘图,但这比就地修改要慢得多,如下所示:

using Plots,Profile
function mcve(n)
    A = rand(n,100,100)
    B = rand(n,100,100)
    l = @layout [ a b ; c]
    p1 = surface(1:100,1:100,A[1,:,:],clims=(0,1),legend=false)
    p2 = heatmap(A[1,:,:],clims=(0,1),aspect_ratio=1,legend=false)
    p3 = heatmap(B[1,:,:],aspect_ratio=1)
    p = plot(p1,p2,p3,layout = l)
    anim = @animate for i=1:n
        surface!(p[1],1:100,1:100,A[i,:,:])
        heatmap!(p[2],A[i,:,:])
        heatmap!(p[3],B[i,:,:])
    end
    gif(anim,"example.gif")
end
mcve(1)
@profile mcve(10)
Profile.print()

跟踪中的结果https://pastebin.com/Lv9uCLE5

根据分析器的说法,将近一半的运行时间都花在函数"setcharheight"上,该函数调用c库。有没有办法减少我需要拨打的电话次数?

我做了一些实验,我发现了两件事可以大大加快绘图过程。

首先,而不是使用表面重新绘制绘图!(( 和热图!((,我只是简单地替换了他们的 :z 系列。这是通过比较代码示例中的第一个函数和第三个函数以及第二个函数和第四个函数来显示的。

第二,GR.jl;设置高度非常慢。这可能是由于 ccall((,这意味着它可能依赖于操作系统。通过将 xtick 和 ytick 设置为 false,实现了显著的加速。这是通过比较示例中的第一个函数到第二个函数以及第三个函数到第四个函数来显示的。

using Plots
function mcve(n,A,B)
    l = @layout [ a b ; c]
    p1 = surface(1:100,1:100,A[1,:,:],clims=(0,1),legend=false)
    p2 = heatmap(A[1,:,:],clims=(0,1),aspect_ratio=1,legend=false)
    p3 = heatmap(B[1,:,:],aspect_ratio=1)
    p = plot(p1,p2,p3,layout = l)
    anim = @animate for i=1:n
        surface!(p[1],1:100,1:100,A[i,:,:])
        heatmap!(p[2],A[i,:,:])
        heatmap!(p[3],B[i,:,:])
    end
    gif(anim,"example1.gif")
end
function mcve4(n,A,B)
    l = @layout [ a b ; c]
    p1 = surface(1:100,1:100,A[1,:,:],clims=(0,1),legend=false,xticks=false,yticks=false)
    p2 = heatmap(A[1,:,:],clims=(0,1),aspect_ratio=1,legend=false,xticks=false,yticks=false)
    p3 = heatmap(B[1,:,:],aspect_ratio=1,xticks=false,yticks=false)
    p = plot(p1,p2,p3,layout = l)
    anim = @animate for i=1:n
        surface!(p[1],1:100,1:100,A[i,:,:],xticks=false,yticks=false)
        heatmap!(p[2],A[i,:,:],xticks=false,yticks=false)
        heatmap!(p[3],B[i,:,:],xticks=false,yticks=false)
    end
    gif(anim,"example4.gif")
end

function mcve2(n,A,B)
    l = @layout [ a b ; c]
    p1 = surface(1:100,1:100,A[1,:,:],clims=(0,1),legend=false,xticks =false,yticks= false)
    p2 = heatmap(A[1,:,:],clims=(0,1),aspect_ratio=1,legend=false,xticks = false,yticks= false)
    p3 = heatmap(B[1,:,:],aspect_ratio=1,xticks = false,yticks= false)
    p = plot(p1,p2,p3,layout = l)
    anim = @animate for i=1:n
        p[1][1][:z] = A[i,:,:]
        p[2][1][:z] = A[i,:,:]
        p[3][1][:z] = B[i,:,:]
    end
    gif(anim,"example2.gif")
end

function mcve3(n,A,B)
    l = @layout [ a b ; c]
    p1 = surface(1:100,1:100,A[1,:,:],clims=(0,1),legend=false)
    p2 = heatmap(A[1,:,:],clims=(0,1),aspect_ratio=1,legend=false)
    p3 = heatmap(B[1,:,:],aspect_ratio=1)
    p = plot(p1,p2,p3,layout = l)
    anim = @animate for i=1:n
        p[1][1][:z] = A[i,:,:]
        p[2][1][:z] = A[i,:,:]
        p[3][1][:z] = B[i,:,:]
    end
    gif(anim,"example3.gif")
end
A = rand(1,100,100)
B = rand(1,100,100)
mcve(1,A,B)
mcve2(1,A,B)
mcve3(1,A,B)
mcve4(1,A,B)
A = rand(10,100,100)
B = rand(10,100,100)
println("Replot,ticks on")
@time mcve(10,A,B)
println("Replot,ticks off")
@time mcve4(10,A,B)
println(":z replace, ticks on")
@time mcve3(10,A,B)
println(":z replace, ticks off")
@time mcve2(10,A,B)

这导致

Replot,ticks on
 19.347849 seconds (12.78 M allocations: 399.848 MiB, 0.30% gc time)
Replot,ticks off
  6.227432 seconds (8.71 M allocations: 298.890 MiB, 0.88% gc time)
:z replace, ticks on
  8.572728 seconds (5.43 M allocations: 149.359 MiB, 0.24% gc time)
:z replace, ticks off
  1.805316 seconds (1.36 M allocations: 48.450 MiB, 0.40% gc time)

相关内容

  • 没有找到相关文章