如何在 Julia 中对单位单位进行直方图绘制?
How to Histogram Unitful Units in Julia?
我想弄清楚如何 bin/histogram Julia 中的数据数组。我有一个来自 Unitful.jl
包的单位数组,我想使用 StatsBase
中的 Histogram
来对数据进行分类。我得到的第一个错误是一个错误,说 log10
没有使用 Unitful.FreeUnits
的方法,所以我写了一个。现在我得到一个尺寸错误。我以为 Unitful 只是要和其他东西一起工作……猜不到。以下是我所在的位置。
using Unitful
using StatsBase
data = [rand()*100*1u"MHz" for x in 1:10000]
function Base.log10(x::Quantity{})
u = unit(x)
return log10(x.val)u
end
# eventually I want to define my bin width manually.. but this is a start.
fit(Histogram, data)
错误
ERROR: DimensionError: 0.0 and 0.8237981449864736 MHz are not dimensionally compatible.
Stacktrace:
[1] _lt at /home/mcamp/.julia/packages/Unitful/1t88N/src/quantities.jl:274 [inlined]
[2] <(::Quantity{Float64,NoDims,Unitful.FreeUnits{(),NoDims,nothing}}, ::Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}}) at /home/mcamp/.julia/packages/Unitful/1t88N/src/quantities.jl:264
[3] <(::Int64, ::Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}}) at /home/mcamp/.julia/packages/Unitful/1t88N/src/quantities.jl:266
[4] <=(::Int64, ::Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}}) at ./operators.jl:326
[5] >=(::Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}}, ::Int64) at ./operators.jl:350
[6] histrange(::Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}}, ::Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}}, ::Int64, ::Symbol) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:51
[7] histrange(::Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}, ::Int64, ::Symbol) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:39
[8] (::StatsBase.var"#127#128"{Symbol})(::Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}, ::Int64) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:103
[9] map(::StatsBase.var"#127#128"{Symbol}, ::Tuple{Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}}, ::Tuple{Int64}) at ./tuple.jl:176
[10] histrange(::Tuple{Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}}, ::Tuple{Int64}, ::Symbol) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:102
[11] fit(::Type{Histogram{Int64,N,E} where E where N}, ::Tuple{Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}}; closed::Symbol, nbins::Int64) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:332
[12] fit(::Type{Histogram{Int64,N,E} where E where N}, ::Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}; closed::Symbol, nbins::Int64) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:276
[13] fit(::Type{Histogram{Int64,N,E} where E where N}, ::Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:276
[14] fit(::Type{Histogram}, ::Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}; kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:383
[15] fit(::Type{Histogram}, ::Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:383
[16] top-level scope at REPL[183]:1
[17] run_repl(::REPL.AbstractREPL, ::Any) at /build/julia/src/julia-1.5.3/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:288
[已编辑,因为我误解了问题]
您要绘制数据直方图吗?如果是,我将使用像 Plots.jl 这样的绘图包的 histogram
函数,而不是 StatsBase.jl。例如,要将来自 Plots.jl 的图与来自 Unitful.jl 的单位结合起来,您可以使用 UnitfulRecipes.jl 包。看看这个 MWE,它可能就是你想要的:
using Unitful: MHz
using Plots
using UnitfulRecipes
data = 100 * exp.(randn(10000)) * MHz
histogram(data)
会输出
[编辑前]
我认为对非无量纲变量(即具有单位的变量)取对数在数学上或物理上没有意义。也就是说,您重新定义 log10
恕我直言,这不是一个好主意。相反,我会在获取日志之前对数据进行非维化,类似于
using Unitful: MHz
using StatsBase
data = 100 * rand(10000) * MHz
data_nodim = log10.(data / MHz) # <- this is valid
fit(Histogram, data_nodim) # <- this is valid too
我想弄清楚如何 bin/histogram Julia 中的数据数组。我有一个来自 Unitful.jl
包的单位数组,我想使用 StatsBase
中的 Histogram
来对数据进行分类。我得到的第一个错误是一个错误,说 log10
没有使用 Unitful.FreeUnits
的方法,所以我写了一个。现在我得到一个尺寸错误。我以为 Unitful 只是要和其他东西一起工作……猜不到。以下是我所在的位置。
using Unitful
using StatsBase
data = [rand()*100*1u"MHz" for x in 1:10000]
function Base.log10(x::Quantity{})
u = unit(x)
return log10(x.val)u
end
# eventually I want to define my bin width manually.. but this is a start.
fit(Histogram, data)
错误
ERROR: DimensionError: 0.0 and 0.8237981449864736 MHz are not dimensionally compatible.
Stacktrace:
[1] _lt at /home/mcamp/.julia/packages/Unitful/1t88N/src/quantities.jl:274 [inlined]
[2] <(::Quantity{Float64,NoDims,Unitful.FreeUnits{(),NoDims,nothing}}, ::Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}}) at /home/mcamp/.julia/packages/Unitful/1t88N/src/quantities.jl:264
[3] <(::Int64, ::Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}}) at /home/mcamp/.julia/packages/Unitful/1t88N/src/quantities.jl:266
[4] <=(::Int64, ::Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}}) at ./operators.jl:326
[5] >=(::Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}}, ::Int64) at ./operators.jl:350
[6] histrange(::Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}}, ::Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}}, ::Int64, ::Symbol) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:51
[7] histrange(::Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}, ::Int64, ::Symbol) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:39
[8] (::StatsBase.var"#127#128"{Symbol})(::Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}, ::Int64) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:103
[9] map(::StatsBase.var"#127#128"{Symbol}, ::Tuple{Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}}, ::Tuple{Int64}) at ./tuple.jl:176
[10] histrange(::Tuple{Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}}, ::Tuple{Int64}, ::Symbol) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:102
[11] fit(::Type{Histogram{Int64,N,E} where E where N}, ::Tuple{Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}}; closed::Symbol, nbins::Int64) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:332
[12] fit(::Type{Histogram{Int64,N,E} where E where N}, ::Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}; closed::Symbol, nbins::Int64) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:276
[13] fit(::Type{Histogram{Int64,N,E} where E where N}, ::Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:276
[14] fit(::Type{Histogram}, ::Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}; kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:383
[15] fit(::Type{Histogram}, ::Array{Quantity{Float64,^-1,Unitful.FreeUnits{(MHz,),^-1,nothing}},1}) at /home/mcamp/.julia/packages/StatsBase/EA8Mh/src/hist.jl:383
[16] top-level scope at REPL[183]:1
[17] run_repl(::REPL.AbstractREPL, ::Any) at /build/julia/src/julia-1.5.3/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:288
[已编辑,因为我误解了问题]
您要绘制数据直方图吗?如果是,我将使用像 Plots.jl 这样的绘图包的 histogram
函数,而不是 StatsBase.jl。例如,要将来自 Plots.jl 的图与来自 Unitful.jl 的单位结合起来,您可以使用 UnitfulRecipes.jl 包。看看这个 MWE,它可能就是你想要的:
using Unitful: MHz
using Plots
using UnitfulRecipes
data = 100 * exp.(randn(10000)) * MHz
histogram(data)
会输出
[编辑前]
我认为对非无量纲变量(即具有单位的变量)取对数在数学上或物理上没有意义。也就是说,您重新定义 log10
恕我直言,这不是一个好主意。相反,我会在获取日志之前对数据进行非维化,类似于
using Unitful: MHz
using StatsBase
data = 100 * rand(10000) * MHz
data_nodim = log10.(data / MHz) # <- this is valid
fit(Histogram, data_nodim) # <- this is valid too