code
julia> using CairoMakie, DataFrames
julia> df_hr = DataFrame(
year = [2017, 2018, 2019, 2020, 2021, 2017, 2018, 2019, 2020, 2021],
mh = [3.7, 4.08, 4.77, 4.69, 5.04, 6.73, 6.9, 6.91, 6.48, 6.3],
type = ["Countryside", "Countryside", "Countryside", "Countryside", "Countryside", "SIB", "SIB", "SIB", "SIB", "SIB"]
)
10×3 DataFrame
Row │ year mh type
│ Int64 Float64 String
─────┼─────────────────────────────
1 │ 2017 3.7 Countryside
2 │ 2018 4.08 Countryside
3 │ 2019 4.77 Countryside
4 │ 2020 4.69 Countryside
5 │ 2021 5.04 Countryside
6 │ 2017 6.73 SIB
7 │ 2018 6.9 SIB
8 │ 2019 6.91 SIB
9 │ 2020 6.48 SIB
10 │ 2021 6.3 SIB
julia> udf=unstack(df_hr,:year,:type,:mh)
5×3 DataFrame
Row │ year Countryside SIB
│ Int64 Float64? Float64?
─────┼──────────────────────────────
1 │ 2017 3.7 6.73
2 │ 2018 4.08 6.9
3 │ 2019 4.77 6.91
4 │ 2020 4.69 6.48
5 │ 2021 5.04 6.3
julia> span(sib,cs) = @. round(100*(sib - cs)/sib; digits=2)
span (generic function with 1 method)
julia> transform!(udf,[[3,2]].=>[span, .-].=>[:deltapc, :delta])
5×5 DataFrame
Row │ year Countryside SIB deltapc delta ⋯
│ Int64 Float64? Float64? Float64 Float ⋯
─────┼───────────────────────────────────────────────
1 │ 2017 3.7 6.73 45.02 3. ⋯
2 │ 2018 4.08 6.9 40.87 2.
3 │ 2019 4.77 6.91 30.97 2.
4 │ 2020 4.69 6.48 27.62 1.
5 │ 2021 5.04 6.3 20.0 1. ⋯
1 column omitted
julia> sdf=stack(udf, [2,3,5])
15×4 DataFrame
Row │ year deltapc variable value
│ Int64 Float64 String Float64?
─────┼───────────────────────────────────────
1 │ 2017 45.02 Countryside 3.7
2 │ 2018 40.87 Countryside 4.08
3 │ 2019 30.97 Countryside 4.77
4 │ 2020 27.62 Countryside 4.69
5 │ 2021 20.0 Countryside 5.04
6 │ 2017 45.02 SIB 6.73
7 │ 2018 40.87 SIB 6.9
8 │ 2019 30.97 SIB 6.91
9 │ 2020 27.62 SIB 6.48
10 │ 2021 20.0 SIB 6.3
11 │ 2017 45.02 delta 3.03
12 │ 2018 40.87 delta 2.82
13 │ 2019 30.97 delta 2.14
14 │ 2020 27.62 delta 1.79
15 │ 2021 20.0 delta 1.26
julia> sort!(sdf,:year)
15×4 DataFrame
Row │ year deltapc variable value
│ Int64 Float64 String Float64?
─────┼───────────────────────────────────────
1 │ 2017 45.02 Countryside 3.7
2 │ 2017 45.02 SIB 6.73
3 │ 2017 45.02 delta 3.03
4 │ 2018 40.87 Countryside 4.08
5 │ 2018 40.87 SIB 6.9
6 │ 2018 40.87 delta 2.82
7 │ 2019 30.97 Countryside 4.77
8 │ 2019 30.97 SIB 6.91
9 │ 2019 30.97 delta 2.14
10 │ 2020 27.62 Countryside 4.69
11 │ 2020 27.62 SIB 6.48
12 │ 2020 27.62 delta 1.79
13 │ 2021 20.0 Countryside 5.04
14 │ 2021 20.0 SIB 6.3
15 │ 2021 20.0 delta 1.26
julia> fig=Figure();
julia> ax = Axis(
fig[2,1],
ylabel = "Montly Income (\$)",
xlabel = "Year"
)
Axis with 0 plots:
julia> bar_lbls=begin
bl=[]
for r in eachrow(udf)
size_arr = "="^Int(trunc(r.delta))
push!(bl,r.Countryside,r.SIB,"")
end
bl
end
15-element Vector{Any}:
3.7
6.73
""
4.08
6.9
""
4.77
6.91
""
4.69
6.48
""
5.04
6.3
""
julia> barplot!(sdf.year, sdf.value,
dodge = repeat([1, 2, 1],5),
stack = repeat([1, 2, 3],5),
color = repeat([1, 2, 3],5),
colormap = [:red, :blue,:white],
bar_labels=bar_lbls,
label_rotation= pi/2,
label_offset=-75,
label_size=repeat([20,20,15],5),
label_color=repeat([:white,:white,:blue],5),
xticks = 2017:2021
)
Combined{Makie.barplot, Tuple{Vector{Point{2, Float32}}}}
julia> size_arr = @. "="^Int(trunc(udf.delta))
5-element Vector{String}:
"==="
"=="
"=="
"="
"="
julia> bl=@. "<"*size_arr *"| " *string(udf.deltapc)*"%"
5-element Vector{String}:
"<===| 45.02%"
"<==| 40.87%"
"<==| 30.97%"
"<=| 27.62%"
"<=| 20.0%"
julia> text!(
bl,
position = Point2f.([2017,2018,2019,2020,2021].-0.2,5.8),
color = :black,
rotation= [pi/2,pi/2,pi/2,pi/2,pi/2],
align = (:center, :center)
)
MakieCore.Text{Tuple{Vector{String}}}
julia> labels = unique(sdf.variable)
3-element Vector{String}:
"Countryside"
"SIB"
"delta"
julia> elements = [PolyElement(polycolor = cgrad(:tab10)[[1,2]][i]) for i in 1:2]
2-element Vector{PolyElement}:
PolyElement(Attributes with 1 entry:
polycolor => RGBA{Float64}(0.1216,0.4667,0.7059,1.0))
PolyElement(Attributes with 1 entry:
polycolor => RGBA{Float64}(1.0,0.498,0.0549,1.0))
julia> el=[elements..., PolyElement(color=:black,markercolor = :transparent, polystrokecolor = :transparent, polypoints = Point{2, Float32}[[0.0, 0.4], [0.0, 0.6], [0.5, 0.6], [0.5,1.0], [1.0, 0.5],[0.5,0.0],[0.5,0.4]])]
3-element Vector{PolyElement}:
PolyElement(Attributes with 1 entry:
polycolor => RGBA{Float64}(0.1216,0.4667,0.7059,1.0))
PolyElement(Attributes with 1 entry:
polycolor => RGBA{Float64}(1.0,0.498,0.0549,1.0))
PolyElement(Attributes with 4 entries:
markercolor => transparent
polycolor => black
polypoints => Point{2, Float32}[[0.0, 0.4], [0.0, 0.6], [0.5, 0.6], [0.5, 1.0], [1.0, 0.5], [0.5, 0.0], [0.5, 0.4]]
polystrokecolor => transparent)
julia> Legend(fig[1,1], el, labels, orientation=:horizontal, tellwidth = false, tellheight = true)
Legend()
julia> fig
julia> save("normal.png", fig) # size = 800 x 600 px
CairoMakie.Screen{IMAGE}