{"spec_id":"climograph-walter-lieth","library":"makie","language":"julia","code":"# anyplot.ai\n# climograph-walter-lieth: Walter-Lieth Climate Diagram\n# Library: makie 0.22.10 | Julia 1.11.9\n# Quality: 90/100 | Created: 2026-06-15\n\nusing CairoMakie\nusing Colors\nusing Statistics\n\nconst THEME       = get(ENV, \"ANYPLOT_THEME\", \"light\")\nconst PAGE_BG     = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nconst ELEVATED_BG = THEME == \"light\" ? colorant\"#FFFDF6\" : colorant\"#242420\"\nconst INK         = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nconst INK_SOFT    = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\nconst INK_MUTED   = THEME == \"light\" ? colorant\"#6B6A63\" : colorant\"#A8A79F\"\n\n# Temperature->red, precipitation->blue: universal climate diagram convention\n# (semantic exception to Imprint palette ordinal ordering)\nconst TEMP_COL   = colorant\"#AE3030\"  # Imprint matte red\nconst PRECIP_COL = colorant\"#4467A3\"  # Imprint blue\n\n# Station: fictional Anatolian-style semi-arid continental climate\n# 1991-2020 climate normals; one frost month, clear summer arid period\nconst STATION  = \"Anatolian Station\"\nconst ELEV     = 894\nconst MLBLS    = [\"J\",\"F\",\"M\",\"A\",\"M\",\"J\",\"J\",\"A\",\"S\",\"O\",\"N\",\"D\"]\nconst TEMP_ARR = Float64[-0.5, 1.2, 6.5, 12.0, 17.0, 21.0, 25.0, 25.0, 20.5, 14.0, 7.5, 2.0]\nconst PREC_ARR = Float64[38.0, 34.0, 40.0, 46.0, 52.0, 30.0, 14.0, 10.0, 18.0, 26.0, 34.0, 40.0]\nconst ANN_T    = round(mean(TEMP_ARR); digits=1)\nconst ANN_P    = Int(round(sum(PREC_ARR)))\n\nconst xs      = collect(1.0:12.0)\nconst prec_sc = PREC_ARR ./ 2.0  # Walter-Lieth 1:2 scaling (10 degC = 20 mm)\n\n# Y limits: buffer below -10 for the frost indicator band\nconst Y_BOT   = -13.0\nconst Y_TOP   = 35.0\nconst FRO_BOT = -13.0\nconst FRO_TOP = -11.0\n\nfig = Figure(\n    size            = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\n# Left axis: temperature (degrees C)\nax = Axis(\n    fig[1, 1];\n    title             = \"climograph-walter-lieth · julia · makie · anyplot.ai\",\n    titlesize         = 18,\n    titlecolor        = INK,\n    backgroundcolor   = PAGE_BG,\n    ylabel            = \"Temperature (°C)\",\n    ylabelsize        = 15,\n    ylabelcolor       = INK,\n    xlabelcolor       = INK,\n    xticklabelsize    = 13,\n    yticklabelsize    = 13,\n    xticklabelcolor   = INK_SOFT,\n    yticklabelcolor   = INK_SOFT,\n    xtickcolor        = INK_SOFT,\n    ytickcolor        = INK_SOFT,\n    leftspinecolor    = INK_SOFT,\n    bottomspinecolor  = INK_SOFT,\n    topspinevisible   = false,\n    rightspinevisible = false,\n    xgridvisible      = false,\n    ygridvisible      = false,\n    xticks            = (collect(1:12), MLBLS),\n    yticks            = collect(-10:10:30),\n)\nylims!(ax, Y_BOT, Y_TOP)\n\n# Right axis: precipitation (mm), scaled 2:1 against the temperature axis\n# ylims are set so that 10 degC on the left = 20 mm on the right\nax_r = Axis(\n    fig[1, 1];\n    yaxisposition      = :right,\n    backgroundcolor    = :transparent,\n    rightspinecolor    = INK_SOFT,\n    yticklabelcolor    = INK_SOFT,\n    ytickcolor         = INK_SOFT,\n    topspinevisible    = false,\n    leftspinevisible   = false,\n    bottomspinevisible = false,\n    xticksvisible      = false,\n    xticklabelsvisible = false,\n    xlabelvisible      = false,\n    xgridvisible       = false,\n    ygridvisible       = false,\n    ylabel             = \"Precipitation (mm)\",\n    ylabelsize         = 15,\n    ylabelcolor        = INK,\n    yticklabelsize     = 13,\n    yticks             = ([0.0, 20.0, 40.0, 60.0], [\"0\", \"20\", \"40\", \"60\"]),\n)\nylims!(ax_r, Y_BOT * 2, Y_TOP * 2)\n\nlinkxaxes!(ax, ax_r)\nxlims!(ax, 0.5, 12.5)\n\n# Humid fill (blue): months where precipitation curve exceeds temperature curve\nband!(ax, xs, TEMP_ARR, max.(TEMP_ARR, prec_sc); color = (PRECIP_COL, 0.40))\n\n# Arid fill (red): months where temperature curve exceeds precipitation curve\nband!(ax, xs, min.(TEMP_ARR, prec_sc), TEMP_ARR; color = (TEMP_COL, 0.30))\n\n# Temperature line (on left axis)\nlines!(ax, xs, TEMP_ARR; color = TEMP_COL, linewidth = 2.5)\n\n# Precipitation line (on right axis, raw mm values)\nlines!(ax_r, xs, PREC_ARR; color = PRECIP_COL, linewidth = 2.5)\n\n# Dashed 0 degC reference line\nhlines!(ax, [0.0]; color = (INK_SOFT, 0.5), linewidth = 1.0, linestyle = :dash)\n\n# Frost indicator blocks for months with mean T < 0 degC\nfor (i, t) in enumerate(TEMP_ARR)\n    if t < 0.0\n        poly!(ax,\n            [Point2f(i - 0.5, FRO_BOT), Point2f(i + 0.5, FRO_BOT),\n             Point2f(i + 0.5, FRO_TOP), Point2f(i - 0.5, FRO_TOP)];\n            color = PRECIP_COL, strokewidth = 0)\n    end\nend\n\n# Station metadata header (data coordinates on left axis)\ntext!(ax, 1.0, 34.0;\n    text     = \"$(STATION)  ($(ELEV) m a.s.l.)\",\n    fontsize = 16,\n    color    = INK,\n    align    = (:left, :top),\n)\ntext!(ax, 1.0, 29.5;\n    text     = \"Mean T = $(ANN_T) °C  ·  Annual P = $(ANN_P) mm  (1991–2020)\",\n    fontsize = 13,\n    color    = INK_SOFT,\n    align    = (:left, :top),\n)\n\n# Legend\nleg_elems = [\n    LineElement(color = TEMP_COL, linewidth = 2.5),\n    LineElement(color = PRECIP_COL, linewidth = 2.5),\n    PolyElement(color = (TEMP_COL, 0.30), strokecolor = :transparent),\n    PolyElement(color = (PRECIP_COL, 0.40), strokecolor = :transparent),\n    PolyElement(color = PRECIP_COL, strokecolor = :transparent),\n]\nleg_labels = [\n    \"Mean temperature\",\n    \"Precipitation\",\n    \"Arid period (T > P/2)\",\n    \"Humid period (P/2 > T)\",\n    \"Frost month (mean T < 0 °C)\",\n]\nLegend(fig[1, 2], leg_elems, leg_labels;\n    framecolor        = (INK_SOFT, 0.3),\n    backgroundcolor   = ELEVATED_BG,\n    labelcolor   = INK,\n    framevisible = true,\n    framewidth   = 1,\n    patchsize    = (22, 12),\n    rowgap       = 6,\n    padding      = (10, 10, 10, 10),\n)\n\ncolsize!(fig.layout, 1, Relative(0.82))\n\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}