Add legend titles for distinct categories in Plots

Is it possible to have legend titles for different categories/classes? Something like in the figure below with continent and pop.

ggplot2_default_legend_title

You can use Plots.jl as follows:

(NB: edited code to be more in line with example provided.)

using Printf, Plots; pgfplotsx()

n = 2   # number of continents
continents = ["Africa" "Europe"]
ci = ["crimson" "darkgreen"]
x1 = [40 , 50 , 60, 65];   y1 = [1e3,4e3, 5e3, 6.5e3];      p1 = [4e8, 8e8, 11e8, 6e8]
x2 = [60, 70, 80, 85, 90]; y2 = [3e3, 5e3, 9e3, 11e3, 7e3]; p2 = [1e8, 5e8, 7e8, 10e8, 8.5e8]
X = [x1, x2]; Y = [y1, y2]; P = [p1, p2]

m = 4  # number of population ranges
pm = minimum(minimum(P)); pM = maximum(maximum(P))
pr = LinRange(pm,pM,m)
P0 = deepcopy(P)
for p in P0, i in 1:length(p)
    p[i] = pr[argmin(abs.(pr .- p[i]))]  # assigns population to one of m-values
end

str = map(x -> @sprintf("%.2g",x), pr)
S = map(x -> x .- pm, P0)
sM = maximum(maximum(S))
md = 3;    # minimum dot size
S = map(x -> md .+ 4 * x ./ sM, S)

Xp = [vcat(X...)[vcat(P0...) .== pr[i]] for i in 1:m ]
Yp = [vcat(Y...)[vcat(P0...) .== pr[i]] for i in 1:m ]
Sp = [vcat(S...)[vcat(P0...) .== pr[i]] for i in 1:m ]
X11 = X[1][1]; Y11 = Y[1][1];

PGFPlotsX.enable_interactive(false)
plt = scatter(xlabel="lifeExp", ylabel="gdpPerCap")
scatter!([X11],[Y11],ms=0, mc=:white, label="Population", legend=:outerright, fg_legend=nothing)
scatter!(Xp, Yp, mc=:lightgrey, ms=Sp', label= permutedims(str), colorbar=false)
scatter!([X11], [Y11], ms=0, mc=:white, label=" ")
scatter!([X11], [Y11], ms=0, mc=:white, label="Continent")
[ scatter!(X[i]', Y[i]', msc=ci[i], mc=ci[i], ms=S[i]', label=false) for i in 1:n ]
[ scatter!([X[i][1]],[Y[i][1]], msc=ci[i], mc=ci[i], ms=md, msw=0, label=continents[i]) for i in 1:n ]
PGFPlotsX.enable_interactive(true)
display(plt)

3 Likes

How to remove these alerts?

julia> scatter(xlabel="lifeExp", ylabel="gdpPerCap")
Error showing value of type Plots.Plot{Plots.PGFPlotsXBackend}:
ERROR: No LaTeX installation found, figures will not be generated. Make sure either pdflatex or lualatex are installed and that the PATH variable is correctly set.
Stacktrace:
  [1] latexengine()
    @ PGFPlotsX C:\Users\Hermesr\.julia\packages\PGFPlotsX\xJiNw\src\build.jl:19
  [2] show(f::IOBuffer, #unused#::MIME{Symbol("image/svg+xml")}, td::PGFPlotsX.TikzDocument)
    @ PGFPlotsX C:\Users\Hermesr\.julia\packages\PGFPlotsX\xJiNw\src\tikzdocument.jl:289
  [3] _show(io::IOBuffer, mime::MIME{Symbol("image/svg+xml")}, plt::Plots.Plot{Plots.PGFPlotsXBackend})
    @ Plots C:\Users\Hermesr\.julia\packages\Plots\FKcum\src\backends\pgfplotsx.jl:1421
  [4] display(d::VSCodeServer.InlineDisplay, m::MIME{Symbol("image/svg+xml")}, x::Plots.Plot{Plots.PGFPlotsXBackend})
    @ VSCodeServer c:\Users\Hermesr\.vscode\extensions\julialang.language-julia-1.2.3\scripts\packages\VSCodeServer\src\display.jl:0
  [5] display(d::VSCodeServer.InlineDisplay, mime::String, x::Any)
    @ Base.Multimedia .\multimedia.jl:216
  [6] display(d::VSCodeServer.InlineDisplay, x::Plots.Plot{Plots.PGFPlotsXBackend})
    @ VSCodeServer c:\Users\Hermesr\.vscode\extensions\julialang.language-julia-1.2.3\scripts\packages\VSCodeServer\src\display.jl:108
  [7] display(x::Any)
    @ Base.Multimedia .\multimedia.jl:328
  [8] #invokelatest#2
    @ .\essentials.jl:708 [inlined]
  [9] invokelatest
    @ .\essentials.jl:706 [inlined]
 [10] print_response(errio::IO, response::Any, show_value::Bool, have_color::Bool, specialdisplay::Union{Nothing, AbstractDisplay})
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:247
 [11] (::REPL.var"#40#41"{REPL.LineEditREPL, Pair{Any, Bool}, Bool, Bool})(io::Any)
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:231
 [12] with_repl_linfo(f::Any, repl::REPL.LineEditREPL)
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:462
 [13] print_response(repl::REPL.AbstractREPL, response::Any, show_value::Bool, have_color::Bool)
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:229
 [14] (::REPL.var"#do_respond#61"{Bool, Bool, REPL.var"#72#82"{REPL.LineEditREPL, REPL.REPLHistoryProvider}, REPL.LineEditREPL, REPL.LineEdit.Prompt})(s::REPL.LineEdit.MIState, buf::Any, ok::Bool)
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:798
 [15] #invokelatest#2
    @ .\essentials.jl:708 [inlined]
 [16] invokelatest
    @ .\essentials.jl:706 [inlined]
 [17] run_interface(terminal::REPL.Terminals.TextTerminal, m::REPL.LineEdit.ModalInterface, s::REPL.LineEdit.MIState)
    @ REPL.LineEdit C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\LineEdit.jl:2441
 [18] run_frontend(repl::REPL.LineEditREPL, backend::REPL.REPLBackendRef)
    @ REPL C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.6\REPL\src\REPL.jl:1126
 [19] (::REPL.var"#44#49"{REPL.LineEditREPL, REPL.REPLBackendRef})()
    @ REPL .\task.jl:411

Install a LaTeX distribution on your computer. Get LaTeX - Mac OS, Windows, Linux

2 Likes

@HerAdri, fyi, running Julia 1.6.1 on Win10 with MiKTeX installed.
Thanks @gustaphe.

NB: edited code above to be more user friendly