【问题标题】:How to Plot a function of two variables in Julia with pyplot如何使用 pyplot 在 Julia 中绘制两个变量的函数
【发布时间】:2016-07-12 19:55:57
【问题描述】:

我正在尝试在 Julia 中使用 pyplot 绘制两个变量的函数。工作起点如下(可在 StackOverflow 找到):

function f(z,t)
    return z*t
end

z = linspace(0,5,11)
t = linspace(0,40,4)

for tval in t
   plot(z, f(z, tval))
end
show()

这对我很有效,并且给了我想要的东西: a field of lines.

我自己的功能如下:

## needed functions ##

const gamma_0 = 6
const Ksch = 1.2
const Kver = 1.5

function Kvc(vc)
    if vc <= 0 
        return 0
    elseif vc < 20 
        return (100/vc)^0.1
    elseif vc < 100
        return 2.023/(vc^0.153)
    elseif vc == 100
        return 1
    elseif vc > 100
        return 1.380/(vc^0.07)
    else 
        return 0
    end
end 

function Kgamma(gamma_t)
    return 1-((gamma_t-gamma_0)/100)
end

function K(gamma_t, vc)
    return Kvc(vc)*Kgamma(gamma_t)*Ksch*Kver
end

我尝试将它们绘制如下:

i = linspace(0,45,10)
j = linspace(0,200,10)
for i_val in i
    plot(i,K(i,j))
end

这给了我以下错误:

isless 没有方法匹配 isless(::Int64, ::Array{Float64,1}) 加载 In[51] 时,从第 3 行开始的表达式中

在 In[17] 的 Kvc 中:2 在无文件的匿名中:4

显然,我的函数无法处理数组。

下一次尝试:

i = linspace(0,200,11)
j = linspace(0,45,11)
for i_val in i
    plot(i_val,map(K,i_val,j))
end

给我一​​个只有轴的空图

谁能给我一个提示...

编辑

一个更简单的例子:

using PyPlot
function P(n,M)
    return (M*n^3)/9550
end
M = linspace(1,5,5)
n = linspace(0,3000,3001)

for M_val in M
    plot(n,P(n,M_val))
end
show()

解决方案

好的,在您的帮助下,我找到了适用于我的缩短示例的解决方案:

function P(n,M)
    result = Array(Float64, length(n))
    for (idx, val) in enumerate(n)
        result[idx] = (M*val^3)/9550
    end
    return result
end
n = linspace(0,3000,3001)

for M_val = 1:5
    plot(n,P(n,M_val))
end
show()

这给了我what I wanted for this shortened example。剩下的问题是:能否以更简单更优雅的方式完成?

我会尝试将其应用于原始示例并在成功时发布。

【问题讨论】:

    标签: matplotlib plot julia


    【解决方案1】:

    我没有完全遵循您想要完成的所有细节,但这里有一些示例,说明如何修改您的几个函数,以便它们接受和返回数组:

    function Kvc(vc)
        result = Array(Float64, length(vc))
        for (idx, val) in enumerate(vc)
            if val <= 0
                result[idx] = 0
            elseif val < 20
                result[idx] = (100/val)^0.1
            elseif val < 100
                result[idx] = 2.023/(val^0.153)
            elseif val == 100
                result[idx] = 1
            elseif val > 100
                result[idx] = 1.380/(val^0.07)
            else
                result[idx] = 0
            end
        end
        return result
    end 
    
    function Kgamma(gamma_t)
        return ones(length(gamma_t))-((gamma_t - gamma_0)/100)
    end
    

    另外,对于你的循环,我想你可能想要这样的东西:

    for i_val in i
        plot(i_val,K(i_val,j))
    end
    

    而不是plot(i, K(i,j),因为那样只会一遍又一遍地打印相同的内容。

    【讨论】:

    • 感谢您的快速回答。我想要实现的是像 [this] (energie.ch/assets/images/article/Bilder/Diagramme/…) 这样的情节。取自 [这里] (energie.ch/asynchronmaschine)。我将缩短并简化我最初的问题,以使我的意图更清楚。
    • @MarcelRüdiger 您要求提示,所以这就是我给的:) 在我看来,您更新的实现很好。我认为没有什么明显的事情可以改进你所做的。
    【解决方案2】:

    &lt; 是为标量定义的。我认为您需要为数组广播它,即使用.&lt;。示例:

    julia> x = 2
    2
    
    julia> x < 3
    true
    
    julia> x < [3 4]
    ERROR: MethodError: no method matching isless(::Int64, ::Array{Int64,2})
    Closest candidates are:
      isless(::Real, ::AbstractFloat)
      isless(::Real, ::Real)
      isless(::Integer, ::Char)
     in <(::Int64, ::Array{Int64,2}) at .\operators.jl:54
     in eval(::Module, ::Any) at .\boot.jl:234
     in macro expansion at .\REPL.jl:92 [inlined]
     in (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at .\event.jl:46
    
    julia> x .< [3 4]
    1x2 BitArray{2}:
     true  true
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-30
      • 1970-01-01
      • 2020-09-07
      • 2021-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多