You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Julia热力图右侧yticks与图例重叠的解决方法咨询

问题描述

我正在创建每行左右两侧均带有yticks的热力图,绘图时遇到右侧yticks与图例重叠的问题。尝试使用right_margin等命令调整yticks或图例位置均未成功,仅在图例右侧增加了空白。恳请提供调整yticks与图例布局的建议,以下是我使用的代码:

using Plots
using Statistics
using DelimitedFiles
using StatsPlots
using DataFrames
using Plots.PlotMeasures
using CSV
using LaTeXStrings

function total_plot_compared_new()
        Catchments=["Feistritz", "Palten", "Gailtal", "Silbertal", "Defreggental", "Pitztal" ]
        Catchments_n=["Feistritztal", "Paltental *", "Gailtal *",  "Silbertal *", "Defreggental", "Pitztal" ]

        obj_title = [L"Obj_{tot}", L"E_{NSE,Q}",L"E_{NSE,log(Q)}", L"E_{VE,Q}", L"E_{NSE,FDC}", L"E_{RE,AC1}", L"E_{NSE,AC90}", L"E_{NSE,RC}", L"E_{AE,SC}"]
        s_calibrations_path = "/01 Model /Calibrations/"

        cal_performance_s = CSV.read("01 Model/04 Results/Calibration/Total/S_Calibration.csv", DataFrame, decimal='.', delim = ',', header=false)
        cal_performance_ns = CSV.read("01 Model/04 Results/Calibration/Total/NS_Calibration.csv", DataFrame, decimal='.', delim = ',', header=false)
        val_performance_s = CSV.read("01 Model/04 Results/Calibration/Total/S_Validation.csv", DataFrame, decimal='.', delim = ',', header=false)
        val_performance_ns = CSV.read("01 Model/04 Results/Calibration/Total/NS_Validation.csv", DataFrame, decimal='.', delim = ',', header=false)
        cal_performance_dif = zeros(6,9)
        val_performance_dif = zeros(6,9)

        for (c,cm) in enumerate(Catchments)

                for (o, ob) in enumerate(obj_title)
                    cal_performance_dif[c,o] = cal_performance_ns[c,o] - cal_performance_s[c,o]
                    val_performance_dif[c,o] = val_performance_ns[c,o] - val_performance_s[c,o]
                end
        end

        cal_performance_s = Matrix(cal_performance_s)
        cal_performance_ns = Matrix(cal_performance_ns)
        val_performance_s = Matrix(val_performance_s)
        val_performance_ns = Matrix(val_performance_ns)

        hm_s = Plots.plot()
        hm_c_s = Plots.heatmap(cal_performance_s, legend=false, c=:RdBu, clims=(-1,1), title="Calibration Sr,cal", titlefont=font(18), xmirror=true)
        for y in 1:1:6
            for x in 1:1:9
                t = round(cal_performance_s[y,x],digits=2)
                    annotate!(x,y,string(t), :white)
            end
        end
        xticks!([1:9;], ["","","","","","","","","",""], xtickfontsize=14)
        yticks!([1:6;], Catchments_n, ytickfont=font(14))
        display(hm_c_s)

        hm_v = Plots.plot()
        hm_v_s = Plots.heatmap(val_performance_s, c=:RdBu, clims=(-1,1), title="Evaluation Sr,cal", titlefont=font(18), ymirror=true)

        for y in 1:1:6
            for x in 1:1:9
                t = round(val_performance_s[y,x],digits=2)
                annotate!(x,y,string(t), :white)
            end
        end
        xticks!([1:9;], ["","","","","","","","",""], xtickfontsize=14)
        yticks!([1:6;], ["F","E","D","C","B","A"], ytickfontsize=14, tickfonthalign=:left)
        total_s = plot(hm_c_s, hm_v_s, layout=(1,2), size=(2500,1000))

        hm_ns = plot()
        hm_c_ns = heatmap(cal_performance_ns, c=:RdBu, clims=(-1,1), legend=false, title="Calibration Sr,clim,adapt", titlefont=font(18))
        for y in 1:1:6
            for x in 1:1:9
                t = round(cal_performance_ns[y,x],digits=2)
                    annotate!(x,y,string(t), :white)
            end
        end
        xticks!([1:9;], ["","","","","","","","",""])
        yticks!([1:6;], Catchments_n, ytickfont=font(14))

        hm_ns = plot()
        hm_v_ns = heatmap(val_performance_ns, c=:RdBu, clims=(-1,1), title="Evaluation Sr,clim,adapt", titlefont=font(18), ymirror=true, ytickfontsize=14)
        for y in 1:1:6
            for x in 1:1:9
                t = round(val_performance_ns[y,x],digits=2)
                    annotate!(x,y,string(t),:white)
            end
        end
        xticks!([1:9;], ["","","","","","","","",""])
        yticks!([1:6;], ["L","K","J","I","H","G"])
        total_ns = plot(hm_c_ns, hm_v_ns, layout=(1,2), size=(2500,1000))

        hm = Plots.plot()
        hm_c_d = heatmap(cal_performance_dif, c=:RdBu, clims=(-0.2,0.2),title="Calibration", legend=false,  titlefont=font(18), ytickfont=18)
        for y in 1:1:6
            for x in 1:1:9
                t = round(cal_performance_dif[y,x],digits=2)
                    annotate!(x,y,string(t), :black)
            end
        end
        xticks!([1:9;], obj_title, xrotation=45, xtickfont=font(14))
        yticks!([1:6;], Catchments_n, ytickfont=font(14))

        hm_v_d = heatmap(val_performance_dif, c=:RdBu, clims=(-0.2,0.2), title="Evaluation", yaxis=nothing, titlefont=font(18), legend_position=:outertopright)

        for y in 1:1:6
            for x in 1:1:9
                t = round(val_performance_dif[y,x],digits=2)
                annotate!(x,y,string(t), :black)
            end
        end
        xticks!([1:9;], obj_title, xrotation=45, xtickfont=font(14), ymirror=true)
        yticks!([1:6;], ["R","Q","P","O","N","M"], ytickfont=font(14))

        total_dif = Plots.plot(hm_c_d, hm_v_d, layout = grid(1,2, widths=[0.46, 0.54]), size=(2500,1100), bottom_margin=30px, top_margin=15px)

        l=@layout[a b{0.55w}; c d{0.55w};e f{0.55w}]
        total_both = Plots.plot(hm_c_s, hm_v_s, hm_c_ns, hm_v_ns, hm_c_d, hm_v_d, layout=l, size=(2500,3000), bottom_margin=10mm, top_margin=1mm)
    
        Plots.savefig("01 Model/04 Results/Calibration/Total/Total_compared_Cal_Val.png")
        
    return
end
解决方案

针对右侧yticks与图例重叠的问题,以下是几个适用于Plots.jl的调整方案:

1. 手动偏移图例位置

使用bbox_to_anchor参数精确控制图例的位置,避免和右侧yticks重叠。修改hm_v_d的创建代码:

hm_v_d = heatmap(val_performance_dif, c=:RdBu, clims=(-0.2,0.2), title="Evaluation", 
                 yaxis=nothing, titlefont=font(18), 
                 legend=:outertopright, bbox_to_anchor=(1.15, 1.0))

bbox_to_anchor的两个数值分别是x、y方向的偏移比例,可根据实际显示效果微调。

2. 给右侧子图单独加右侧边距

不要在总布局中设置right_margin,而是给右侧子图单独预留yticks空间:

hm_v_d = heatmap(val_performance_dif, c=:RdBu, clims=(-0.2,0.2), title="Evaluation", 
                 yaxis=nothing, titlefont=font(18), legend_position=:outertopright,
                 right_margin=20mm)

同时调整右侧yticks的对齐方式,避免超出边界:

yticks!([1:6;], ["R","Q","P","O","N","M"], ytickfont=font(14), tickfonthalign=:right)

3. 调整布局宽度分配

在总布局的grid设置中,增大右侧子图的宽度比例,给yticks和图例留出足够空间:

total_dif = Plots.plot(hm_c_d, hm_v_d, layout = grid(1,2, widths=[0.44, 0.56]), 
                       size=(2500,1100), bottom_margin=30px, top_margin=15px)

4. 将图例移到总布局顶部

如果不需要子图单独显示图例,可把图例统一放到整个布局的顶部,避免和子图yticks冲突:

total_both = Plots.plot(hm_c_s, hm_v_s, hm_c_ns, hm_v_ns, hm_c_d, hm_v_d, layout=l, 
                        size=(2500,3000), bottom_margin=10mm, top_margin=10mm,
                        legend=:outertop, legend_columns=1)

同时记得给每个子图添加legend=false,关闭子图自身的图例。

内容的提问来源于stack exchange,提问作者Magali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 11:08:11