如何控制Julia双面板图中热力图的宽高比为1?
Julia Makie双面板图:热力图强制宽高比1的问题解决
问题描述
想要用Julia绘制双面板图,左侧为热力图,右侧为直方图,初始代码如下(数组X和向量y为已知数据):
begin f = Figure() CairoMakie.heatmap(f[1,1], X) CairoMakie.hist(f[1,2], y) f end
希望强制左侧热力图宽高比为1,尝试手动创建Axis并设置aspect=1后,代码如下:
begin f = Figure() ax1 = Axis(f[1,1], aspect = 1) ax2 = Axis(f[1,2]) CairoMakie.heatmap(ax1, X) CairoMakie.hist(ax2, y) f end
运行后出现如下错误:
`Makie.convert_arguments` for the plot type MakieCore.Heatmap{Tuple{Makie.MakieLayout.Axis, Matrix{Float64}}} and its conversion trait MakieCore.DiscreteSurface() was unsuccessful. The signature that could not be converted was: ::Makie.MakieLayout.Axis, ::Matrix{Float32} Makie needs to convert all plot input arguments to types that can be consumed by the backends (typically Arrays with Float32 elements). You can define a method for `Makie.convert_arguments` (a type recipe) for these types or their supertypes to make this set of arguments convertible (See http://makie.juliaplots.org/stable/documentation/recipes/index.html). Alternatively, you can define `Makie.convert_single_argument` for single arguments which have types that are unknown to Makie but which can be converted to known types and fed back to the conversion pipeline. error(::String)@error.jl:33 var"#convert_arguments#144"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(MakieCore.convert_arguments), ::Type{MakieCore.Heatmap{Tuple{Makie.MakieLayout.Axis, Matrix{Float64}}}}, ::Makie.MakieLayout.Axis, ::Vararg{Any})@conversions.jl:17 convert_arguments(::Type{MakieCore.Heatmap{Tuple{Makie.MakieLayout.Axis, Matrix{Float32}}}}, ::Makie.MakieLayout.Axis, ::Matrix{Float32})@conversions.jl:8 convert_arguments_individually(::Type{MakieCore.Heatmap{Tuple{Makie.MakieLayout.Axis, Matrix{Float64}}}}, ::Makie.MakieLayout.Axis, ::Vararg{Any})@conversions.jl:51 var"#convert_arguments#144"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(MakieCore.convert_arguments), ::Type{MakieCore.Heatmap{Tuple{Makie.MakieLayout.Axis, Matrix{Float64}}}}, ::Makie.MakieLayout.Axis, ::Vararg{Any})@conversions.jl:14 convert_arguments(::Type{MakieCore.Heatmap{Tuple{Makie.MakieLayout.Axis, Matrix{Float64}}}}, ::Makie.MakieLayout.Axis, ::Matrix{Float64})@conversions.jl:8 var"#plot!#139"(::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, ::typeof(MakieCore.plot!), ::Makie.Scene, ::Type{MakieCore.Heatmap}, ::MakieCore.Attributes, ::Makie.MakieLayout.Axis, ::Matrix{Float64})@interfaces.jl:302 plot!(::Makie.Scene, ::Type{MakieCore.Heatmap}, ::MakieCore.Attributes, ::Makie.MakieLayout.Axis, ::Matrix{Float64})@interfaces.jl:288 var"#plot#929"(::NamedTuple{(), Tuple{}}, ::NamedTuple{(), Tuple{}}, ::Base.Pairs{Symbol, Any, Tuple{Symbol, Symbol}, NamedTuple{(:colorrange, :colormap), Tuple{Tuple{Int64, Int64}, Symbol}}}, ::typeof(MakieCore.plot), ::Type{MakieCore.Heatmap}, ::Makie.MakieLayout.Axis, ::Vararg{Any})@figureplotting.jl:28 var"#heatmap#19"(::Base.Pairs{Symbol, Any, Tuple{Symbol, Symbol}, NamedTuple{(:colorrange, :colormap), Tuple{Tuple{Int64, Int64}, Symbol}}}, ::typeof(MakieCore.heatmap), ::Makie.MakieLayout.Axis, ::Vararg{Any})@recipes.jl:33 top-level scope@Local: 6
错误解析
这个错误的核心原因是Makie的API调用方式错误:
CairoMakie.heatmap()函数默认用于创建新的绘图场景或轴并绘制热力图,第一个参数应为布局位置(如f[1,1]),而非已有的Axis对象。- 若要在已创建好的Axis上绘制,必须使用带感叹号的突变版本函数
heatmap!(),直方图对应hist!()。直接将Axis传给不带感叹号的heatmap,Makie无法识别该参数组合,导致参数转换失败。
解决方案
提供两种可行的实现方式:
方式1:手动创建Axis并使用突变绘图函数
修正API调用,用heatmap!和hist!在已创建的Axis上绘制:
begin f = Figure() ax1 = Axis(f[1,1], aspect = 1) # 设置宽高比为1 ax2 = Axis(f[1,2]) CairoMakie.heatmap!(ax1, X) # 用!版本在已有Axis上绘制 CairoMakie.hist!(ax2, y) # 直方图同理 f end
方式2:直接在布局位置设置轴属性(更简洁)
无需手动创建Axis,直接通过axis关键字参数在heatmap函数中设置宽高比:
begin f = Figure() CairoMakie.heatmap(f[1,1], X, axis=(aspect=1,)) # 直接指定轴的宽高比 CairoMakie.hist(f[1,2], y) f end
两种方式都能实现左侧热力图宽高比强制为1的需求,方式2代码更简洁,适合快速实现。
内容的提问来源于stack exchange,提问作者seeker_after_truth
相关产品推荐
相关产品推荐

