JuliaGeometry / MeshViz.jl

Makie.jl recipes for visualization of Meshes.jl

Home Page:https://github.com/JuliaGeometry/Meshes.jl

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Colors are not correct for categorical values

ErickChacon opened this issue · comments

While investigating the issue with colorbars and categorical values, I noticed that the colors given to categorical values do not seem right, and it just takes the few first values of the colorscheme.

import CairoMakie: CairoMakie as MK, save, Figure, Axis
using Meshes, MeshViz
using CategoricalArrays

# data
ps = rand(Point2, 100)
variable = categorical(rand(["a", "b", "c", "d", "e"], 100))

# MeshViz
fig, ax, hm = viz(ps, color = variable, colorscheme = :RdBu)
fig

meshviz

We can see that only red colors from the colorscheme are taken. While I would expect a graph like the following.

# Makie
x = [coordinates(p)[1] for p in ps]
y = [coordinates(p)[2] for p in ps]
c = levelcode.(variable)
fig, ax, hm = MK.scatter(x, y, color = c, colorrange = (0.5, maximum(c) + 0.5),
    colormap = MK.cgrad(:RdBu, 5, categorical = true, rev = true))
MK.Colorbar(fig[1, 2], hm, ticks = (1:5, ["a", "b", "c", "d", "e"]))
fig

makie

In addition to that, we get an error if the number of categories is greater then 11 (the number of colors intantiated from the colorscheme). The fix for this this is probably easy but I am just exploring the possibilities to have an approach that allow us to work with numerical and categorical values, but also allows easy integration with Colorbar.

# data
ps = rand(Point2, 100)
variable = categorical(rand(1:15 100))

# MeshViz
fig, ax, hm = viz(ps, color = variable, colorscheme = :RdBu)
ERROR: BoundsError: attempt to access 11-element Array{RGB{Float64},1} with eltype ColorTypes.RGB{Float64} at index [13]
Stacktrace:
  [1] getindex
    @ ./array.jl:924 [inlined]
  [2] getindex
    @ ~/.julia/packages/ColorSchemes/lTeyu/src/ColorSchemes.jl:213 [inlined]
  [3] ascolor
    @ ~/documents/repositories/MeshViz-play.jl/src/colors.jl:8 [inlined]
  [4] _broadcast_getindex_evalf
    @ ./broadcast.jl:670 [inlined]
  [5] _broadcast_getindex
    @ ./broadcast.jl:643 [inlined]
  [6] getindex
    @ ./broadcast.jl:597 [inlined]
  [7] macro expansion
    @ ./broadcast.jl:961 [inlined]
  [8] macro expansion
    @ ./simdloop.jl:77 [inlined]
  [9] copyto!
    @ ./broadcast.jl:960 [inlined]
 [10] copyto!
    @ ./broadcast.jl:913 [inlined]
 [11] copy
    @ ./broadcast.jl:885 [inlined]
 [12] materialize
    @ ./broadcast.jl:860 [inlined]
 [13] tocolors(values::CategoricalVector{Int64, UInt32, Int64, CategoricalValue{Int64, UInt32}, Union{}}, scheme::ColorSchemes.ColorScheme{Vector{ColorTypes.RGB{Float64}}, String, String})
    @ MeshViz ~/documents/repositories/MeshViz-play.jl/src/colors.jl:37
 [14] process(values::CategoricalVector{Int64, UInt32, Int64, CategoricalValue{Int64, UInt32}, Union{}}, scheme::Symbol, alphas::Float64)
    @ MeshViz ~/documents/repositories/MeshViz-play.jl/src/colors.jl:65
 [15] (::MeshViz.var"#106#129")(arg1#357::CategoricalVector{Int64, UInt32, Int64, CategoricalValue{Int64, UInt32}, Union{}}, arg2#358::Float64, arg3#359::Symbol)
    @ MeshViz ./none:0
 [16] #map#13
    @ ~/.julia/packages/Observables/PHGQ8/src/Observables.jl:564 [inlined]
 [17] map(::MeshViz.var"#106#129", ::Observables.Observable{Any}, ::Observables.Observable{Any}, ::Observables.Observable{Any})
    @ Observables ~/.julia/packages/Observables/PHGQ8/src/Observables.jl:562
 [18] plot!(plot::MakieCore.Combined{MeshViz.viz, Tuple{PointSet{2, Float64}}})
    @ MeshViz ~/documents/repositories/MeshViz-play.jl/src/collection.jl:18
 [19] plot!(scene::MakieCore.Combined{MeshViz.viz, Tuple{Vector{Point2}}}, P::Type{MakieCore.Combined{MeshViz.viz, Tuple{PointSet{2, Float64}}}}, attributes::MakieCore.Attributes, input::Tuple{Observables.Observable{PointSet{2, Float64}}}, args::Observables.Observable{Tuple{PointSet{2, Float64}}})
    @ Makie ~/.julia/packages/Makie/Iqcri/src/interfaces.jl:442
 [20] plot!(scene::MakieCore.Combined{MeshViz.viz, Tuple{Vector{Point2}}}, P::Type{MakieCore.Combined{MeshViz.viz}}, attributes::MakieCore.Attributes, args::Observables.Observable{PointSet{2, Float64}}; kw_attributes::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Makie ~/.julia/packages/Makie/Iqcri/src/interfaces.jl:344
 [21] plot!
    @ ~/.julia/packages/Makie/Iqcri/src/interfaces.jl:311 [inlined]
 [22] #plot!#167
    @ ~/.julia/packages/Makie/Iqcri/src/interfaces.jl:295 [inlined]
 [23] viz!(::MakieCore.Combined{MeshViz.viz, Tuple{Vector{Point2}}}, ::Vararg{Any}; attributes::Base.Pairs{Symbol, Observables.Observable{Any}, NTuple{7, Symbol}, NamedTuple{(:size, :color, :alpha, :colorscheme, :facetcolor, :showfacets, :decimation), NTuple{7, Observables.Observable{Any}}}})
    @ MeshViz ~/.julia/packages/MakieCore/6sckc/src/recipes.jl:38
 [24] plot!(plot::MakieCore.Combined{MeshViz.viz, Tuple{Vector{Point2}}})
    @ MeshViz ~/documents/repositories/MeshViz-play.jl/src/fallbacks.jl:13
 [25] plot!(scene::Makie.Scene, P::Type{MakieCore.Combined{MeshViz.viz, Tuple{Vector{Point2}}}}, attributes::MakieCore.Attributes, input::Tuple{Observables.Observable{Vector{Point2}}}, args::Observables.Observable{Tuple{Vector{Point2}}})
    @ Makie ~/.julia/packages/Makie/Iqcri/src/interfaces.jl:432
 [26] plot!(scene::Makie.Scene, P::Type{MakieCore.Combined{MeshViz.viz}}, attributes::MakieCore.Attributes, args::Vector{Point2}; kw_attributes::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Makie ~/.julia/packages/Makie/Iqcri/src/interfaces.jl:344
 [27] plot!(scene::Makie.Scene, P::Type{MakieCore.Combined{MeshViz.viz}}, attributes::MakieCore.Attributes, args::Vector{Point2})
    @ Makie ~/.julia/packages/Makie/Iqcri/src/interfaces.jl:311
 [28] plot(P::Type{MakieCore.Combined{MeshViz.viz}}, args::Vector{Point2}; axis::NamedTuple{(), Tuple{}}, figure::NamedTuple{(), Tuple{}}, kw_attributes::Base.Pairs{Symbol, Any, Tuple{Symbol, Symbol}, NamedTuple{(:color, :colorscheme), Tuple{CategoricalVector{Int64, UInt32, Int64, CategoricalValue{Int64, UInt32}, Union{}}, Symbol}}})
    @ Makie ~/.julia/packages/Makie/Iqcri/src/figureplotting.jl:48
 [29] #viz#1
    @ ~/.julia/packages/MakieCore/6sckc/src/recipes.jl:34 [inlined]
 [30] top-level scope
    @ REPL[1048]:2

Thank you @ErickChacon for reporting the issue. Looking forward to a unified fix. The colorbar would be really nice to have in the viewer so that users don't need to fight with Makie all the time to figure out how to do it properly. Also, the scientific type of the variable being plotted tells us a lot about the type of colorbar and colorscheme used, and we already dispatch on scientific types here in our preprocessing pipeline.

Hi @ErickChacon the problem in your MWE is that the colorscheme you picked is for continuous variables. If you omit the colorscheme option, the recipe will pick a categorical colorscheme with distingushable colors:

image

You can also provide a colorscheme that is categorical and things should work.