Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New colorscheme for Plots.jl 2.0 #4966

Open
isentropic opened this issue Jul 18, 2024 · 11 comments · May be fixed by JuliaPlots/PlotUtils.jl#167
Open

New colorscheme for Plots.jl 2.0 #4966

isentropic opened this issue Jul 18, 2024 · 11 comments · May be fixed by JuliaPlots/PlotUtils.jl#167

Comments

@isentropic
Copy link
Member

@BeastyBlacksmith @t-bltg
So I've been on search on new colorschemes and what we could choose. I think we should also update the color gradient while at it too. Upon hearing feedback I think we should settle with colorblind friendly scheme:
https://juliagraphics.github.io/ColorSchemes.jl/stable/basics/#For-CVD-(color-vision-deficient-or-%22color-blind:)-users
Upon which tol_bright looks good to me
https://juliagraphics.github.io/ColorSchemes.jl/stable/basics/#For-CVD-(color-vision-deficient-or-%22color-blind:)-users
looks good to ne

For the colorgradient, upon watching this and this setting viridis or some of the other 3 would be good in my opinion.

I'm hoping we could reach some consensus here

@isentropic
Copy link
Member Author

isentropic commented Jul 18, 2024

These look really good as suggested by @cormullion esp the batlow gradient and catergorical if it is as good as advertised

@BeastyBlacksmith
Copy link
Member

@cormullion can I also get the categorial palette of the scientific gradients somehow in ColorSchemes.jl?

@BeastyBlacksmith
Copy link
Member

BeastyBlacksmith commented Jul 18, 2024

Its hard to judge without examples, so here is some code and pictures:

using StatsPlots
@userplot BackendPlot
@recipe function f(bp::BackendPlot; n = 4, colorgradient = :inferno)
           t = range(0, 3π, length = 100)
           d = rand(3, 3)

           plot_title := "p = $(plotattributes[:color_palette]), cg = $colorgradient"
           layout := n

           @series begin
               subplot := 1
               f = s -> -cos(s) * log(s)
               g = t -> sin(t) * log(t)
               f1 = s -> -cos(s) * log(s) + 5
               g1 = t -> sin(t) * log(t) + 5
               f2 = s -> -cos(s) * log(s) + 10
               g2 = t -> sin(t) * log(t) + 10
               linewidth --> 3
               [f g f1 g1 f2 g2]
           end

           @series begin
               subplot := 2 + (n > 2)
               RecipesBase.recipetype(:groupedbar, d)
           end

           if n > 2
               @series begin
                   subplot := 2
                   line_z := t
                   label := false
                   seriestype := surface
                   seriescolor := colorgradient
                   t, t, (x, y) -> x * sin(x) - y * cos(y)
               end

               @series begin
                   subplot := 4
                   seriestype := contourf
                   seriescolor := colorgradient
                   t, t, (x, y) -> x * sin(x) - y * cos(y)
               end
           end
       end

schemes = [:batlowW, :batlowK, :lipari, :navia, :imola, :devon, :lajolla, :bamako, :davos, :bilbao, :lapaz, :acton]

mkdir("plots_colors")
for scheme in fschemes
     savefig(backendplot(colorgradient = scheme, palette = :tol_bright), joinpath("plots_colors", "$scheme.png"))
end

lapaz
acton
navia
lajolla
imola
devon
davos
lipari
batlowK

@BeastyBlacksmith
Copy link
Member

I like navia, lajolla, devon and lipari

@cormullion
Copy link

ColorSchemes.jl is very minimalist - the SVG swatches in the docs are drawn with Luxor.

Screenshot 2024-07-18 at 15 01 00
Code
using Luxor, ColorSchemes

function draw_scheme(schemename, pos=O;
  swatchwidth=800,
  swatchheight=20)
  @layer begin
      translate(pos)
      cols = colorschemes[schemename].colors
      setline(0.5)
      t = Tiler(swatchwidth, swatchheight, 1, length(cols), margin = 0)
      for (i, c) in enumerate(cols)
          sethue(c)
          box(t, i, :fillstroke)
      end
      sethue("white")
      text(string(schemename), Point(-swatchwidth/2 - 20, 0), halign=:right)
  end
end

schemes = [
  :mpetroff_10,
  :tol_YlOrBr,
  :tol_land_cover,
  :tol_light,
  :mk_15,
  :mpetroff_6,
  :tol_ylorbr,
  :tol_PRGn,
  :tol_medcontrast,
  :tol_prgn,
  :okabe_ito,
  :tol_highcontrast,
  :ibm_cvd,
  :tol_BuRd,
  :mk_12,
  :tol_rainbow,
  :tol_muted,
  :tol_iridescent,
  :tol_bright,
  :tol_incandescent,
  :tol_vibrant,
  :tol_bu_rd,
  :tol_sunset,
  :mpetroff_8,
  :mk_8,
  :tol_nightfall,
]

Drawing(650, 700,  "/tmp/cs.svg")
origin()
background("#121212")
translate(boxtopcenter() + (0, 30))
for cs in schemes
  draw_scheme(cs, swatchwidth=450)
  translate(0, 25)
end
finish()
preview()

(I would use Plots.jl if I were a Plots.jl user. :))

I think seeing them in action -in a plot - is a good idea. But don't forget Dark Mode (like often happens)!

@BeastyBlacksmith
Copy link
Member

ColorSchemes.jl is very minimalist - the SVG swatches in the docs

Thats not what I meant. On their homepage they have sequential continuous palettes, discrete palettes and categorial palettes. But in ColorSchemes.jl I can only find the first two.

@isentropic
Copy link
Member Author

lajola looks great and inline with notion of heatmap (as in heat). tol_bright and lajola are a good candidate for the new default. Maybe we should see about this batlow and the categorical variant of it too

@cormullion
Copy link

cormullion commented Jul 19, 2024

@BeastyBlacksmith Ah, I’m with you now.

ColorSchemes.jl is mostly Crameri-v5.0 (ca 2020), with minor corrections. Incorporating the complete Crameri-v8.0 set wouldn’t be too much work - could be done by next week.

Version 3.26 includes the -S scientific schemes now - eg batlowS.

@isentropic
Copy link
Member Author

isentropic commented Jul 22, 2024

batlowS looks weird in that the primary color isnt bright blue
image

https://juliagraphics.github.io/ColorSchemes.jl/stable/catalogue/#Color-Vision-Deficient-friendly-schemes :tol_bright looks good
I like :tol_bright and :lajolla colors. I would also go one step further and recommend :managua usage for diverging colorschemes.
image

I also like :seaborn_colorblind as it resembles matplotlib default and would be more famliar to most users.
image
They also have other variants including gradients that look good. Link here too.

Overall seaborn colors and :tol_bright + scientific gradients both look good to me. I wouldn't mind having either of those. I'm slightly leaning toward seaborn as the look a little more conventional (close to matplotlib).

@BeastyBlacksmith
Copy link
Member

BeastyBlacksmith commented Jul 26, 2024

I'm slightly leaning toward seaborn as the look a little more conventional (close to matplotlib).

I think, being distinct is a good thing.

I made some more examples for palettes using the gradients identified before:

tol_bright

tol_bright_devon_black
tol_bright_devon_white
tol_bright_lajolla_black
tol_bright_lajolla_white
tol_bright_lipari_black
tol_bright_lipari_white
tol_bright_navia_black
tol_bright_navia_white

tol_light

tol_light_devon_black
tol_light_devon_white
tol_light_lajolla_black
tol_light_lajolla_white
tol_light_lipari_black
tol_light_lipari_white
tol_light_navia_black
tol_light_navia_white

seaborn_colorblind

seaborn_colorblind_devon_black
seaborn_colorblind_devon_white
seaborn_colorblind_lajolla_black
seaborn_colorblind_lajolla_white
seaborn_colorblind_lipari_black
seaborn_colorblind_lipari_white
seaborn_colorblind_navia_black
seaborn_colorblind_navia_white

There is something neat about having the same colors in gradient and palette, but this would possibly only work with batlow:

batlow

batlowS_batlow_black
batlowS_batlowK_black
batlowS_batlowK_white
batlowS_batlow_white

code ```julia using StatsPlots @userplot BackendPlot @recipe function f(bp::BackendPlot; n = 4, colorgradient = :inferno) t = range(0, 3π, length = 100) d = rand(3, 3)
       plot_title := "p = $(plotattributes[:color_palette]), cg = $colorgradient"
       layout := n

       @series begin
           subplot := 1
           f = s -> -cos(s) * log(s)
           g = t -> sin(t) * log(t)
           f1 = s -> -cos(s) * log(s) + 5
           g1 = t -> sin(t) * log(t) + 5
           f2 = s -> -cos(s) * log(s) + 10
           g2 = t -> sin(t) * log(t) + 10
           linewidth --> 3
           [f g f1 g1 f2 g2]
       end

       @series begin
           subplot := 2 + (n > 2)
           RecipesBase.recipetype(:groupedbar, d)
       end

       if n > 2
           @series begin
               subplot := 2
               line_z := t
               label := false
               seriestype := surface
               seriescolor := colorgradient
               t, t, (x, y) -> x * sin(x) - y * cos(y)
           end

           @series begin
               subplot := 4
               seriestype := contourf
               seriescolor := colorgradient
               t, t, (x, y) -> x * sin(x) - y * cos(y)
           end
       end
   end

schemes = [:lipari, :navia, :devon, :lajolla, :batlow, :batlowK]

mkdir("plots_colors")

for (scheme, palette, background) in Iterators.product(schemes, [:tol_bright, :tol_light, :seaborn_colorblind, :batlowS], [:white, :black])
savefig(backendplot(colorgradient = scheme, palette = palette, bg = background), joinpath("plots_colors", "$(palette)$(scheme)$(background).png"))
end

</details>

@BeastyBlacksmith
Copy link
Member

but I think we narrowed the options enough, that I could make a poll on discourse

@BeastyBlacksmith BeastyBlacksmith linked a pull request Aug 29, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants