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

如何在Makie.jl中正确设置Colorbar的tickformat显示整数?

问题描述

我的绘图效果如下:
绘图效果

我想将Colorbar改为显示简单整数,尝试使用tickformat但语法有误,例如以下代码会直接将刻度标记显示为字面量"%.0f":

Mke.Colorbar(fig[1, 2], limits=extrema(longt.rat), colormap="hawaii", scale=log10, tickformat="%.0f", label="Multiple of national average\nfunding per capita")

请问该如何解决?以下是最小可复现示例(MWE):

using GeoStats, GeoIO, CSV, DataFrames, Colors, ColorSchemes
import CairoMakie as Mke

# List of London Boroughs
lon = ["Westminster", "Ealing", "Kingston upon Thames", "Islington", "Merton", "Hackney", "Camden", "Wandsworth", "Enfield", "Southwark", "City of London", "Lambeth", "Hillingdon", "Tower Hamlets", "Kensington and Chelsea", "Greenwich", "Haringey", "Richmond upon Thames", "Hounslow", "Harrow", "Lewisham", "Hammersmith and Fulham", "Newham", "Waltham Forest", "Croydon", "Brent", "Redbridge", "Barnet", "Bromley", "Barking and Dagenham", "Havering", "Sutton", "Bexley"]

# Shape file from ONS
print("Reading shapefile         ... ")
@time LAs = GeoIO.load("LAD_DEC_2023_UK_BFC.shp") |> Rename("LAD23CD" => "LADcode")

# Subset of CSV data just covering London
combo = DataFrame(
    LADcode=["E09000033", "E09000009", "E09000021", "E09000019", "E09000024", "E09000012", "E09000007", "E09000032", "E09000010", "E09000028", "E09000001", "E09000022", "E09000017", "E09000030", "E09000020", "E09000011", "E09000014", "E09000027", "E09000018", "E09000015", "E09000023", "E09000013", "E09000025", "E09000031", "E09000008", "E09000005", "E09000026", "E09000003", "E09000006", "E09000002", "E09000016", "E09000029", "E09000004"],
    newLocalAuthority=["Westminster", "Ealing", "Kingston upon Thames", "Islington", "Merton", "Hackney", "Camden", "Wandsworth", "Enfield", "Southwark", "City of London", "Lambeth", "Hillingdon", "Tower Hamlets", "Kensington and Chelsea", "Greenwich", "Haringey", "Richmond upon Thames", "Hounslow", "Harrow", "Lewisham", "Hammersmith and Fulham", "Newham", "Waltham Forest", "Croydon", "Brent", "Redbridge", "Barnet", "Bromley", "Barking and Dagenham", "Havering", "Sutton", "Bexley"],
    Total_Awarded=[1551248258, 110166558, 38033540, 865003501, 46621989, 395602425, 915273792, 197296888, 86772623, 573171051, 321575633, 665770100, 39514648, 374049415, 307431197, 812345843, 181261693, 176262413, 131028168, 48236040, 173721339, 257659057, 246970981, 95473179, 86525712, 304128061, 77681457, 82934564, 88862200, 63604751, 46974062, 42463929, 41183878],
    subpop=[205087, 366127, 167845, 216767, 215324, 259956, 210390, 328367, 329601, 306374, 8618, 317498, 304792, 312273, 143940, 289254, 264130, 195232, 287940, 260987, 299810, 183295, 350626, 278050, 390506, 338918, 309836, 388639, 329830, 218534, 262022, 209517, 246543]
    )

print("Processing data           ... ")
@time begin
# Funding per capita
    natave = sum(skipmissing(combo.Total_Awarded)) / sum(skipmissing(combo.subpop))
    combo.rat .= (combo.Total_Awarded) ./ (combo.subpop) ./ natave
    col = log10.(combo.rat)
    mini = minimum(col)
    maxi = maximum(col)
end

print("Joining combo to geometry ... ")
@time begin
# Add combo to the GeoTable
    table1 = values(LAs) |> DataFrame
    table1.index = [i for i in 1:nrow(table1)]
    leftjoin!(table1, combo, on=:LADcode, matchmissing=:equal)
    sort!(table1, :index)
    gt = georef(table1, LAs.geometry)
end

# Draw a map with colorbar
function citymap(gt, LA_List, title)
    longt = gt |> Filter(row -> !ismissing(row.newLocalAuthority) && row.newLocalAuthority in LA_List)
    col = log10.(longt.rat) # Can't currently have consistent colours across different plots
    fig, ax, v = viz(longt.geometry, color=col, colorscheme=:hawaii, colorrange=extrema(col), facetcolor="black", showfacets=true)
    Mke.Colorbar(fig[1, 2], limits=extrema(longt.rat), colormap="hawaii", scale=log10, #=tickformat="%.0f",=# label="Multiple of national average\nfunding per capita")
    Mke.Label(fig[0, :], title, fontsize=30)
    ax.aspect = Mke.DataAspect()
    Mke.hidedecorations!(ax)
    Mke.display(fig)
end
@time citymap(gt, lon, "Greater London")
解决方案

在CairoMakie中,当Colorbar使用对数刻度(scale=log10)时,直接传入字符串格式的tickformat不会生效——因为对数刻度的内部数值是原始值的对数,需要先转换回原始值再格式化。可以通过以下两种方法解决:

方法一:自定义格式化函数

将tickformat设置为匿名函数,把对数刻度值转换回原始倍数后格式化为整数:

Mke.Colorbar(fig[1, 2], limits=extrema(longt.rat), colormap="hawaii", scale=log10, 
             tickformat=x -> string(round(Int, 10^x)), 
             label="Multiple of national average\nfunding per capita")

这里10^x将对数刻度值还原为原始的倍数数值,round(Int, ...)取整后转成字符串显示。

方法二:手动指定刻度位置与标签

先确定需要显示的整数刻度(比如1、2、5、10等),再手动设置ticks参数:

# 定义想要显示的整数刻度值
desired_ticks = [1, 2, 5, 10]
# 转换为对数刻度对应的位置
log_ticks = log10.(desired_ticks)
# 设置Colorbar
Mke.Colorbar(fig[1, 2], limits=extrema(longt.rat), colormap="hawaii", scale=log10, 
             ticks=(log_ticks, string.(desired_ticks)), 
             label="Multiple of national average\nfunding per capita")

这种方法能精确控制显示的刻度内容,适合需要固定整数标签的场景。

将上述任意一种方法替换到代码中注释掉的tickformat部分,即可让Colorbar显示整数刻度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 00:58:10