Search code examples
juliamakie.jl

How to make legend for scatter plot in Makie plots?


Suppose I have the following data:

using DataFrames, CairoMakie, RDatasets

iris_df = dataset("datasets", "iris")[:, 1:4];

preds = rand((0, 1), 150)

Now I want to draw a scatter plot with a legend and arbitrary labels:

p = scatter(
  iris_df[:, 2], iris_df[:, 3],
  color=preds,
  dpi=300,
)

enter image description here

Now I want to add a legend for it, But I'm unsuccessful.
What I've tried:

julia> Legend(p, ["label2", "label1"])

ERROR: MethodError: no method matching _block(::Type{Legend}, ::Makie.FigureAxisPlot, ::Vector{String})
Closest candidates are:
  _block(::Type{<:Makie.Block}, ::Union{GridPosition, GridSubposition}, ::Any...; kwargs...) at C:\Users\Shayan\.julia\packages\Makie\Ggejq\src\makielayout\blocks.jl:287
  _block(::Type{<:Makie.Block}, ::Union{Figure, Scene}, ::Any...; bbox, kwargs...) at C:\Users\Shayan\.julia\packages\Makie\Ggejq\src\makielayout\blocks.jl:298

Or:

f = Figure()
Axis(f[1, 1])

p = scatter!(
  iris_df[:, 2], iris_df[:, 3],
  color=preds,
  dpi=300,
)

Legend(p, ["label2", "label1"])


ERROR: MethodError: no method matching _block(::Type{Legend}, ::Scatter{Tuple{Vector{Point{2, Float32}}}}, ::Vector{String})
Closest candidates are:
  _block(::Type{<:Makie.Block}, ::Union{GridPosition, GridSubposition}, ::Any...; kwargs...) at C:\Users\Shayan\.julia\packages\Makie\Ggejq\src\makielayout\blocks.jl:287
  _block(::Type{<:Makie.Block}, ::Union{Figure, Scene}, ::Any...; bbox, kwargs...) at C:\Users\Shayan\.julia\packages\Makie\Ggejq\src\makielayout\blocks.jl:298

Solution

  • Based on the maintainers' claim, this can't be done automatically yet. But one way is to can make the legend manually:

    fig, ax, p = scatter(
      iris_df[:, 2], iris_df[:, 3],
      color=preds, dpi=300,
      size=(50, 50),
    )
    
    elem_1, elem_2 = (
      [
        MarkerElement(
        color = :black,
        marker = :square,
        markersize = 15
        )
      ],
      [
        MarkerElement(
        color = :yellow,
        marker = :square,
        markersize = 15
        )
      ]
    )
    
    Legend(
      fig[1, 2],
      [elem_1, elem_2],
      ["label 1", "label 2"],
      "Legend"
    )
    display(fig)
    

    enter image description here

    Helpful links: [1], [2]