gpt4 book ai didi

Julia Plotly 不显示带有子图的 plotly

转载 作者:行者123 更新时间:2023-12-04 04:23:54 31 4
gpt4 key购买 nike

我之前做了一些解决方法来在 Julia Plotly 中实现精彩的子图,但目前正在努力解决一个更复杂的问题。下面有三种方法可以完成这项工作。 draw1 完美地完成了,但不适用于我的情况,draw2 不适用,draw3 在 REPL 中适用,但在其他情况下不适用。

这里是预期的图形矩阵,也就是子图。 expected matrix of graphs

draw1 完成工作 -> 出现预期的图形矩阵

function draw1()
[plot([1,1,1]) plot([2,2,2]); plot([3,3,3]) plot([4,4,4])]
end

draw2a 和 draw2b 不会,无论是作为模块的函数调用还是复制到 REPL 中

function draw2a()
local mx = [1 2; 3 4]
local p(i) = plot([i,i,i])
p.(mx)
end
function draw2b()
local mx = [1 2; 3 4]
local p = map(i-> plot([i,i,i]), collect(1:4))
p[mx]
end

REPL 对 draw2a 和 draw2b 做同样的事情:

julia> subplots.draw2()
2×2 Array{PlotlyJS.SyncPlot,2}:
SyncPlot(data: [
"scatter with fields type, x, and y"
]
...
followed by the content of the graphs

如果复制到 REPL 中,draw3 可以完美地完成工作,但如果被调用则不会

function draw3()
local p(i) = plot([i,i,i])
eval(Meta.parse("[p(1) p(2); p(3) p(4)]"))
end

如果调用:

julia> subplots.draw3()
ERROR: UndefVarError: p not defined

一定是范围问题

最佳答案

修复

以下是对draw2a的修改哪个有效(即它显示了预期的图形):

function draw4()
local mx = [1 2; 3 4]
local p(i) = plot([i,i,i])
matrix_with_plots = p.(mx)
hvcat((2, 2), matrix_with_plots...)
end

理解为什么hvcat显示预期的图形,我们必须退后一步并了解如何 SyncPlot有效。

如何SyncPlot工作?

让我们以draw1为例代码:

[plot([1,1,1]) plot([2,2,2]); plot([3,3,3]) plot([4,4,4])]

Shell 通过以下步骤处理此代码块:

  1. plot([1,1,1])电话 PlotlyJS.plot ,它创建了一个 SyncPlot object ,其中包含 plotly 信息和一些元数据。另一个PlotlyJS.plot的来电函数产生相似的对象。

  2. [a b; c d]只是 Base.hvcat((2, 2), a, b, c, d) 的语法糖. (2, 2)元组意味着应创建一个 2x2 矩阵。所以下一步是 Julia shell 调用 Base.hvcat function(2, 2)元组和我们的图作为参数:Base.hvcat((2, 2), sync_plot1, sync_plot2, sync_plot3, sync_plot4) .

  3. 但是(扭曲!)Base.hvcat函数有一个专门针对 SyncPlot 的方法对象,在 PlotlyJS/utils.jl 中定义:

    # subplot methods on syncplot
    Base.hcat(sps::SyncPlot...) = SyncPlot(hcat([sp.plot for sp in sps]...))
    Base.vcat(sps::SyncPlot...) = SyncPlot(vcat([sp.plot for sp in sps]...))
    Base.vect(sps::SyncPlot...) = vcat(sps...)
    Base.hvcat(rows::Tuple{Vararg{Int}}, sps::SyncPlot...) =
    SyncPlot(hvcat(rows, [sp.plot for sp in sps]...))

    这意味着不是执行 Base.hvcat 的通用内置版本函数并创建一个通常的 Array , Julia 调用 PlotlyJS 自己的 Base.hvcat函数,产生一个新的 SyncPlot目的。这个新SyncPlot对象将前面的四个 plotly 封装为子 plotly 。

  4. 当 Julia shell 完成代码块的计算时,它会尝试显示结果。它通过调用 Base.display function 来实现。关于代码块的返回值。

    在我们的例子中,代码块的返回值是 SyncPlot , 所以 Base.display(<our SyncPlot>)被称为。

  5. 但是(另一个转折点!)Base.display函数有一个专门针对 SyncPlot 的方法对象,在 PlotlyJS/display.jl 中定义:

    Base.display(::PlotlyJSDisplay, p::SyncPlot) = display_blink(p::SyncPlot)

    这意味着不是执行 Base.display 的通用内置版本函数并将数据结构打印到控制台,Julia 调用 PlotlyJS 自己的 Base.display函数,它会打开 AtomShell 窗口并在那里显示图形。

最后一点也意味着你可以调用display明确地。以下调用打开四个窗口,其中包含四个图:

for i in 1:4 display(plot([i, i, i])) end

为什么 hvcat调用修复代码?

matrix_with_plots draw4 中的变量是一个包含绘图的普通 Julia 矩阵。这是由 draw2a 返回的.因此当display函数被调用,display只需在控制台上打印数据结构。

调用 hvcat ,我们调用 PlotlyJS 的自定义 hvcat ,它创建了一个 SyncPlot有四个子图(与包含四个 SyncPlot 对象的普通 Julia 矩阵相反)。

关于Julia Plotly 不显示带有子图的 plotly ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58341823/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com