# Scatter plot with multiple labels per point

**URL:** <https://discourse.julialang.org/t/scatter-plot-with-multiple-labels-per-point/102477>\
**Category:** Visualization\
**Created:** [August 4, 2023, 9:42am UTC](https://discourse.julialang.org/t/scatter-plot-with-multiple-labels-per-point/102477 "2023-08-04T09:42:35Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![DrChainsaw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drchainsaw/32/8497_2.png) [@DrChainsaw](https://discourse.julialang.org/u/DrChainsaw)\
**Post date:** [August 4, 2023, 9:42am UTC](https://discourse.julialang.org/t/scatter-plot-with-multiple-labels-per-point/102477/1 "2023-08-04T09:42:35Z")

</div>

Suppose I have some a set of items like this:

```julia
stuct DummyItem
 x::Float64
 y::Float64
 labels::Vector{String}
end

```

Where `labels` can have 10-100 elements but only up to max 10 or so unique values.

Is there a good way to visualize a set of `DummyItems` (size of set is expected to be in order of 100 items)?

One way I could think of is to make a scatter plot with the `x` and `y` values and let each point be a pie-chart (and the legend will then be one color per unique label string). I’m of course open to better ways to do it.

Is there a way to make such a plot? I’m currently using Plots.jl with the GR backend, but I’m not locked in to it.

Context in case it matters: I’m currently looking into making the optimizer rule a per-layer search space in [NaiveGAflux](https://github.com/DrChainsaw/NaiveGAflux.jl). The animation on the readme has an example of how the plot looks today with a single optimiser per model. The change means there will be a population of arbitrary neural network architectures where each architecture has one set of optimizer hyperparameters per operation with trainable parameters.

---

<div class="post-metadata">

**Author:** ![DrChainsaw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/drchainsaw/32/8497_2.png) [@DrChainsaw](https://discourse.julialang.org/u/DrChainsaw)\
**Post date:** [August 6, 2023, 3:25pm UTC](https://discourse.julialang.org/t/scatter-plot-with-multiple-labels-per-point/102477/2 "2023-08-06T15:25:29Z")

</div>

This is the brute-force:ish solution I ended up with when I got around to it. Could probably be made easier with plot recepies, but for now I just want to see if this is at all useful to display my data.

```julia
# Draws a single pie chart with center at (x,y)
function plotpie!(plt, labs, x,y; seen, colors, markersize=0.1)
       ulabs = unique(labs)
       fracs = [2pi * count(==(lab), labs) / length(labs) for lab in ulabs]
       start = 0.0
       sectors = similar(fracs, Shape)
       for i in eachindex(fracs)
           sectors[i] = Shape(vcat((x,y), map(p -> p .+ (x,y), Plots.partialcircle(start, start + fracs[i], 50, markersize)), (x,y)))
       start += fracs[i]
       end
       for (sector, lab) in zip(sectors, ulabs)
           maybec = get(seen, lab, nothing)
           color, label = if isnothing(maybec)
               color = colors[length(seen)+1]
               seen[lab] = color
               color, lab
           else
               maybec, false
           end
           plot!(plt, sector; label, color, linecolor=color)
       end
       plt
end

# Entry point
function plotpie(ps)
       ulabs = unique(mapreduce(p -> p.labels, vcat, ps))
       colors = palette(:jet, length(ulabs))
       seen = Dict()
       plt = plot()
       for p in ps
        plotpie!(plt, p.labels, p.x, p.y; seen, colors)
       end
       plot!(plt, aspect_ratio=:equal, legend=:outertopright)
       plt
end

# Test it out
genitem(n) = (labels = string.(rand('a':'f', n)), x = randn(), y = randn())

plotpie([genitem(rand(1:100)) for _ in 1:20])

```

![image](https://global.discourse-cdn.com/julialang/original/3X/c/1/c14598797c823d819758f9a994b8f85a345eeb22.png)
