diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 42e421a6e..86033fcbd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,6 +77,7 @@ jobs: (; path="."), (; path="./GraphRecipes"), (; path="./StatsPlots"), + (; path="./PlotThemes"), ]) - name: Install conda based matplotlib @@ -92,7 +93,15 @@ jobs: cmd=(xvfb-run ${cmd[@]}) fi echo ${cmd[@]} - ${cmd[@]} -e 'using Pkg; Pkg.test(["RecipesBase", "RecipesPipeline", "PlotsBase", "Plots", "GraphRecipes", "StatsPlots"]; coverage=true)' + ${cmd[@]} -e 'using Pkg; Pkg.test([ + "RecipesBase", + "RecipesPipeline", + "PlotsBase", + "Plots", + "GraphRecipes", + "StatsPlots", + "PlotThemes", + ]; coverage=true)' - uses: julia-actions/julia-processcoverage@latest if: startsWith(matrix.os, 'ubuntu') with: diff --git a/PlotThemes/LICENSE.md b/PlotThemes/LICENSE.md new file mode 100644 index 000000000..775bc2312 --- /dev/null +++ b/PlotThemes/LICENSE.md @@ -0,0 +1,22 @@ +The PlotThemes.jl package is licensed under the MIT "Expat" License: + +> Copyright (c) 2016: Patrick Kofod Mogensen. +> +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in all +> copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +> SOFTWARE. +> diff --git a/PlotThemes/Project.toml b/PlotThemes/Project.toml new file mode 100644 index 000000000..418c81f93 --- /dev/null +++ b/PlotThemes/Project.toml @@ -0,0 +1,17 @@ +name = "PlotThemes" +uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" +version = "3.3.0" + +[deps] +PlotUtils = "995b91a9-d308-5afd-9ec6-746e21dbc043" +Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[compat] +PlotUtils = "1" +julia = "1" + +[extras] +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["Test"] diff --git a/PlotThemes/README.md b/PlotThemes/README.md new file mode 100644 index 000000000..5ce6439f9 --- /dev/null +++ b/PlotThemes/README.md @@ -0,0 +1,114 @@ +# PlotThemes + +[![Build Status](https://travis-ci.org/JuliaPlots/PlotThemes.jl.svg?branch=master)](https://travis-ci.org/JuliaPlots/PlotThemes.jl) + +#### Primary author: Patrick Kofod Mogensen (@pkofod) + +PlotThemes is a package to spice up the plots made with [Plots.jl](https://github.com/JuliaPlots/Plots.jl). To install: + +```julia +Pkg.add("PlotThemes") +``` + +## Using PlotThemes + +Currently the following themes are available: +- `:default` +- `:dark` +- `:ggplot2` +- `:juno` +- `:lime` +- `:orange` +- `:sand` +- `:solarized` +- `:solarized_light` +- `:wong` +- `:wong2` +- `:gruvbox_dark` +- `:gruvbox_light` +- `:bright` +- `:vibrant` +- `:mute` +- `:dao` +- `:dracula` +- `:rose_pine` +- `:rose_pine_dawn` + + +When using Plots, a theme can be set using the `theme` function: +```julia +using Plots +theme(thm::Symbol; kwargs...) +``` +`theme` accepts any Plots [attribute](https://docs.juliaplots.org/stable/attributes/) as keyword argument and sets its value as default for subsequent plots. + +Themes can be previewed using `Plots.showtheme(thm::Symbol)`: + +### `:default` +![theme_default](https://user-images.githubusercontent.com/16589944/70847841-7ca7ea00-1e69-11ea-851e-e99d8559260d.png) + +### `:dark` +![theme_dark](https://user-images.githubusercontent.com/16589944/70847843-8d586000-1e69-11ea-9e39-5d4c44865750.png) + +### `:ggplot2` +![theme_ggplot2](https://user-images.githubusercontent.com/16589944/70847847-99442200-1e69-11ea-9ae8-ddd10ec4a303.png) + +### `:juno` +![theme_juno](https://user-images.githubusercontent.com/16589944/70847860-be389500-1e69-11ea-88b9-2a3bb3bbcf64.png) + +### `:lime` +![theme_lime](https://user-images.githubusercontent.com/16589944/70847863-c55fa300-1e69-11ea-8de7-3ef2a3a8ce30.png) + +### `:orange` +![theme_orange](https://user-images.githubusercontent.com/16589944/70847866-cf81a180-1e69-11ea-813a-7e4394311ef2.png) + +### `:sand` +![theme_sand](https://user-images.githubusercontent.com/16589944/70847868-d4deec00-1e69-11ea-8aab-de94af02bbfe.png) + +### `:solarized` +![theme_solarized](https://user-images.githubusercontent.com/16589944/70847869-dad4cd00-1e69-11ea-930e-b145e19bcff5.png) + +### `:solarized_light` +![theme_solarized_light](https://user-images.githubusercontent.com/16589944/70847872-df998100-1e69-11ea-955a-7fcc2e7043de.png) + +### `:wong` +![theme_wong](https://user-images.githubusercontent.com/16589944/70847875-e58f6200-1e69-11ea-904d-d4f7e27bb181.png) + +### `:wong2` +![theme_wong2](https://user-images.githubusercontent.com/16589944/70847880-eaecac80-1e69-11ea-9b59-cdf937427121.png) + +### `:gruvbox_dark` +![theme_gruvbox_dark](https://user-images.githubusercontent.com/16589944/70847882-f049f700-1e69-11ea-94f8-255f2cd17288.png) + +### `:gruvbox_light` +![theme_gruvbox_light](https://user-images.githubusercontent.com/16589944/70847885-fb048c00-1e69-11ea-9546-4dc0d9e4154c.png) + +### `:bright` +![theme_bright](https://user-images.githubusercontent.com/16589944/70848065-8ed75780-1e6c-11ea-8e59-9882b3c4a4db.png) + +### `:vibrant` +![theme_vibrant](https://user-images.githubusercontent.com/16589944/70848066-926ade80-1e6c-11ea-91ba-fd08d14e6963.png) + +### `:mute` +![theme_mute](https://user-images.githubusercontent.com/16589944/70848069-9860bf80-1e6c-11ea-9cac-8a797d526835.png) + +### `:dao` +![theme_dao](https://user-images.githubusercontent.com/7330605/106512313-54de7000-64c9-11eb-98d5-2aee3603879a.png) + +### `:dracula` +![theme_dracula](https://user-images.githubusercontent.com/64332767/136754217-31d4348a-c873-4496-8b66-905e4d8a7e36.png) + +### `:rose_pine` +![theme_rose_pine](https://github.com/BaerLKR/PlotThemes.jl/assets/83340886/30c869e5-2b90-405a-bc49-cf4ef3c43d75) + +### `:rose_pine_dawn` +![theme_rose_pine_dawn](https://github.com/BaerLKR/PlotThemes.jl/assets/83340886/e30c0b46-1be3-49f5-afc5-ceede0b0c27d) + +## Contributing +A theme specifies default values for different Plots [attributes](https://docs.juliaplots.org/stable/attributes/). +At the moment these are typically colors, palettes and colorgradients, but any Plots attribute can be controlled by a theme in general. +PRs for new themes very welcome! Adding a new theme (e.g. `mytheme`) is as easy as adding a new file (mytheme.jl) that contains at least the following line: +```julia +_themes[:mytheme] = PlotTheme(; kwargs...) +``` +The keyword arguments can be any collection of Plots attributes plus a colorgradient keyword argument. diff --git a/PlotThemes/src/PlotThemes.jl b/PlotThemes/src/PlotThemes.jl new file mode 100644 index 000000000..f00cdc48b --- /dev/null +++ b/PlotThemes/src/PlotThemes.jl @@ -0,0 +1,85 @@ +module PlotThemes + +using PlotUtils + +export add_theme, theme_palette, PlotTheme + +_255_to_1(c::Symbol, colors) = RGBA(map(x-> x/255,colors[c])...) +RGB255(r,g,b) = RGB(r/255, g/255, b/255) + +function expand_palette(bg, cs; kwargs...) + colors = palette(cs).colors.colors + c = convert.(RGBA, distinguishable_colors(20, vcat(bg, colors); kwargs...))[2:end] + return palette(c) +end + +const KW = Dict{Symbol, Any} + +struct PlotTheme + defaults::KW +end + +PlotTheme(; kw...) = PlotTheme(KW(kw)) + +# adjust an existing theme +PlotTheme(base::PlotTheme; kw...) = PlotTheme(KW(base.defaults..., KW(kw)...)) + +"Get the palette of a PlotTheme" +function theme_palette(s::Symbol) + if haskey(_themes, s) && haskey(_themes[s].defaults, :palette) + return _themes[s].defaults[:palette] + else + return palette(:default) + end +end + + +# add themes +include("dark.jl") +include("ggplot2.jl") +include("solarized.jl") +include("sand.jl") +include("lime.jl") +include("orange.jl") +include("wong.jl") +include("boxed.jl") +include("juno.jl") +include("gruvbox.jl") +include("sheet.jl") +include("dao.jl") +include("dracula.jl") +include("rose_pine.jl") + + +const _themes = Dict{Symbol, PlotTheme}([ + :default => PlotTheme(), + :dao => _dao, + :dark => _dark, + :ggplot2 => _ggplot2, + :gruvbox_light => _gruvbox_light, + :gruvbox_dark => _gruvbox_dark, + :solarized => _solarized, + :solarized_light => _solarized_light, + :sand => _sand, + :bright => _bright, + :vibrant => _vibrant, + :mute => _mute, + :wong => _wong, + :wong2 => _wong2, + :boxed => _boxed, + :juno => _juno, + :lime => _lime, + :orange => _orange, + :dracula => _dracula, + :rose_pine => _rose_pine, + :rose_pine_dawn => _rose_pine_dawn + +]) + + +function add_theme(s::Symbol, thm::PlotTheme) + _themes[s] = thm +end + + +end # module diff --git a/PlotThemes/src/boxed.jl b/PlotThemes/src/boxed.jl new file mode 100644 index 000000000..664febb48 --- /dev/null +++ b/PlotThemes/src/boxed.jl @@ -0,0 +1,16 @@ +const _boxed = PlotTheme(Dict([ + :minorticks => true, + :grid => false, + :frame => :box, + :guidefontvalign => :top, + :guidefonthalign => :right, + :foreground_color_legend => nothing, + :legendfontsize => 9, + :legend => :topright, + :xlim => (:auto,:auto), + :ylim => (:auto,:auto), + :label => "", + :palette => expand_palette(colorant"white", [RGB(0,0,0); wong_palette]; + lchoices = [57], + cchoices = [100]) + ])) diff --git a/PlotThemes/src/dao.jl b/PlotThemes/src/dao.jl new file mode 100644 index 000000000..c17cc01d0 --- /dev/null +++ b/PlotThemes/src/dao.jl @@ -0,0 +1,28 @@ +const dao_palette = [ + colorant"#d77255", + colorant"#009afa", + colorant"#707070", + colorant"#21ab74", + colorant"#ba3030", + colorant"#9467bd" +] + +const _dao = PlotTheme(Dict([ + :background => :white, + :framestyle => :box, + :grid => true, + :gridalpha => 0.4, + :linewidth => 1.4, + :markerstrokewidth => 0, + :fontfamily => "Computer Modern", + :colorgradient => :magma, + :guidefontsize => 12, + :titlefontsize => 12, + :tickfontsize => 8, + :palette => dao_palette, + :minorgrid => true, + :minorticks => 5, + :gridlinewidth => 0.7, + :minorgridalpha => 0.06, + :legend => :outertopright]) +) diff --git a/PlotThemes/src/dark.jl b/PlotThemes/src/dark.jl new file mode 100644 index 000000000..6946ece1b --- /dev/null +++ b/PlotThemes/src/dark.jl @@ -0,0 +1,22 @@ +#inspired by nucleus theme for Atom +const dark_palette = [ + colorant"#FE4365", # red + colorant"#eca25c", # orange + colorant"#3f9778", # green + colorant"#005D7F" # blue +] +const dark_bg = colorant"#363D46" + +const _dark = PlotTheme(Dict([ + :bg => dark_bg, + :bginside => colorant"#30343B", + :fg => colorant"#ADB2B7", + :fgtext => colorant"#FFFFFF", + :fgguide => colorant"#FFFFFF", + :fglegend => colorant"#FFFFFF", + :legendfontcolor => colorant"#FFFFFF", + :legendtitlefontcolor => colorant"#FFFFFF", + :titlefontcolor => colorant"#FFFFFF", + :palette => expand_palette(dark_bg, dark_palette; lchoices = [57], cchoices = [100]), + :colorgradient => :fire]) +) diff --git a/PlotThemes/src/dracula.jl b/PlotThemes/src/dracula.jl new file mode 100644 index 000000000..1ea16ea87 --- /dev/null +++ b/PlotThemes/src/dracula.jl @@ -0,0 +1,28 @@ +# Names follow: +# https://draculatheme.com/contribute#color-palette +const dracula_palette = [ + colorant"#8be9fd" # Cyan + colorant"#ff79c6" # Pink + colorant"#50fa7b" # Green + colorant"#bd93f9" # Purple + colorant"#ffb86c" # Orange + colorant"#ff5555" # Red + colorant"#f1fa8c" # Yellow + colorant"#6272a4" # Comment +] +const dracula_bg = colorant"#282a36" +const dracula_fg = colorant"#f8f8f2" + +const _dracula = PlotTheme(Dict([ + :bg => dracula_bg, + :bginside => colorant"#30343B", + :fg => dracula_fg, + :fgtext => dracula_fg, + :fgguide => dracula_fg, + :fglegend => dracula_fg, + :legendfontcolor => dracula_fg, + :legendtitlefontcolor => dracula_fg, + :titlefontcolor => dracula_fg, + :palette => expand_palette(dracula_bg, dracula_palette), + :colorgradient => :viridis]) +) diff --git a/PlotThemes/src/ggplot2.jl b/PlotThemes/src/ggplot2.jl new file mode 100644 index 000000000..a6856488c --- /dev/null +++ b/PlotThemes/src/ggplot2.jl @@ -0,0 +1,64 @@ +# # unfished +# add_theme(:ggplot2_base, +# bglegend = _invisible, +# fg = :white, +# fglegend = _invisible, +# fgguide = :black) +# +# add_theme(:ggplot2, +# base = :ggplot2_base, +# bginside = :lightgray, +# fg = :lightgray, +# fgtext = :gray, +# fglegend = :gray, +# fgguide = :black) +# +# add_theme(:ggplot2_grey, base = :ggplot2) +# +# add_theme(:ggplot2_bw, +# base = :ggplot2_base, +# bginside = :white, +# fg = :black, +# fgtext = :lightgray, +# fglegend = :lightgray, +# fgguide = :black) + +const _ggplot_colors = Dict( + :gray92 => RGB(fill(0.92, 3)...), + :gray20 => RGB(fill(0.2, 3)...), + :gray30 => RGB(fill(0.3, 3)...) + ) + + +const _ggplot2 = PlotTheme(Dict([ + ## Background etc + :bg => :white, + :bginside => _ggplot_colors[:gray92], + :bglegend => _ggplot_colors[:gray92], + :fglegend => :white, + :fgguide => :black, + :widen=>true, + ## Axes / Ticks + #framestyle => :grid, + #foreground_color_tick => _ggplot_colors[:gray20], # tick color not yet implemented + :foreground_color_axis => _ggplot_colors[:gray20], # tick color + :tick_direction=>:out, + :foreground_color_border =>:white, # axis color + :foreground_color_text => _ggplot_colors[:gray30], # tick labels + :gridlinewidth => 1, + #tick label size => *0.8, + ### Grid + :foreground_color_grid => :white, + :gridalpha => 1, + ### Minor Grid + :minorgrid => true, + :minorgridalpha => 1, + :minorgridlinewidth=>0.5, # * 0.5 + :foreground_color_minor_grid=>:white, + #foreground_color_minortick=>:white, ## not yet implemented + :minorticks => 2, + ## Lines and markers + :markerstrokealpha => 0, + :markerstrokewidth => 0 ]) + #showaxis=> :false +) diff --git a/PlotThemes/src/gruvbox.jl b/PlotThemes/src/gruvbox.jl new file mode 100644 index 000000000..d822e2c1f --- /dev/null +++ b/PlotThemes/src/gruvbox.jl @@ -0,0 +1,68 @@ +# https://github.com/morhetz/gruvbox +const _gruvbox_dark_palette = (:bright_green, :bright_yellow, :bright_blue, :bright_aqua, :bright_purple, :bright_red, :bright_orange) + +const _gruvbox_light_palette = (:faded_green, :faded_yellow, :faded_blue, :faded_aqua, :faded_purple, :faded_red, :faded_orange) + +const _gruvbox_colors = Dict( + :dark0_hard => RGB255(29,32,33), + :dark0 => RGB255(40,40,40), + :dark0_soft => RGB255(50,48,47), + :dark1 => RGB255(60,56,54), + :dark2 => RGB255(80,73,69), + :dark3 => RGB255(102,92,84), + :dark4 => RGB255(124,111,100), + :dark4_256 => RGB255(124,111,100), + :gray_245 => RGB255(146,131,116), + :gray_244 => RGB255(146,131,116), + :light0_hard => RGB255(249,245,215), + :light0 => RGB255(253,244,193), + :light0_soft => RGB255(242,229,188), + :light1 => RGB255(235,219,178), + :light2 => RGB255(213,196,161), + :light3 => RGB255(189,174,147), + :light4 => RGB255(168,153,132), + :light4_256 => RGB255(168,153,132), + :bright_red => RGB255(251,73,52), + :bright_green => RGB255(184,187,38), + :bright_yellow => RGB255(250,189,47), + :bright_blue => RGB255(131,165,152), + :bright_purple => RGB255(211,134,155), + :bright_aqua => RGB255(142,192,124), + :bright_orange => RGB255(254,128,25), + :neutral_red => RGB255(204,36,29), + :neutral_green => RGB255(152,151,26), + :neutral_yellow => RGB255(215,153,33), + :neutral_blue => RGB255(69,133,136), + :neutral_purple => RGB255(177,98,134), + :neutral_aqua => RGB255(104,157,106), + :neutral_orange => RGB255(214,93,14), + :faded_red => RGB255(157,0,6), + :faded_green => RGB255(121,116,14), + :faded_yellow => RGB255(181,118,20), + :faded_blue => RGB255(7,102,120), + :faded_purple => RGB255(143,63,113), + :faded_aqua => RGB255(66,123,88), + :faded_orange => RGB255(175,58,3), +) + +const _gruvbox_dark = PlotTheme(Dict([ + :bg => _gruvbox_colors[:dark2], + :bginside => _gruvbox_colors[:dark0], + :fg => _gruvbox_colors[:light3], + :fgtext => _gruvbox_colors[:light3], + :fgguide => _gruvbox_colors[:dark1], + :fglegend => _gruvbox_colors[:light3], + :palette => expand_palette(_gruvbox_colors[:dark3], [_gruvbox_colors[c] for c in _gruvbox_dark_palette]), + :colorgradient => cgrad(:YlOrRd, rev = true) ]) +) + +const _gruvbox_light = PlotTheme(Dict([ + :bg => _gruvbox_colors[:light1], + :bginside => _gruvbox_colors[:light0], + :fg => _gruvbox_colors[:dark1], + :fgtext => _gruvbox_colors[:dark1], + :fgguide => _gruvbox_colors[:dark1], + :fglegend => _gruvbox_colors[:dark1], + :palette => expand_palette(_gruvbox_colors[:light3], [_gruvbox_colors[c] for c in _gruvbox_light_palette]), + :colorgradient => cgrad(:YlOrRd, rev = true) ]) +) diff --git a/PlotThemes/src/juno.jl b/PlotThemes/src/juno.jl new file mode 100644 index 000000000..ddb36bd00 --- /dev/null +++ b/PlotThemes/src/juno.jl @@ -0,0 +1,20 @@ +#inspired by nucleus theme for Atom +const juno_palette = [ + colorant"#FE4365", # red + colorant"#eca25c", # orange + colorant"#3f9778", # green + colorant"#005D7F" # blue +] + +const juno_bg = colorant"#282C34" + +const _juno = PlotTheme(Dict([ + :bg => juno_bg, + :bginside => colorant"#21252B", + :fg => colorant"#ADB2B7", + :fgtext => colorant"#9EB1BE", + :fgguide => colorant"#9EB1BE", + :fglegend => colorant"#9EB1BE", + :palette => expand_palette(juno_bg, juno_palette; lchoices = [57], cchoices = [100]), + :colorgradient => :fire ]) +) diff --git a/PlotThemes/src/lime.jl b/PlotThemes/src/lime.jl new file mode 100644 index 000000000..ba21d6bf0 --- /dev/null +++ b/PlotThemes/src/lime.jl @@ -0,0 +1,20 @@ +# a blue/green/yellow theme of no specific origin +const lime_palette = reverse([colorant"#271924", # dark blue + colorant"#394256", # semi dark blue + colorant"#30727F", # green blue + colorant"#36A58F", # turqoise + colorant"#80D584", # green, + colorant"#EBFB73"]) # yellow + +const black = lime_palette[6] + +const _lime = PlotTheme(Dict([ + :bg => black, + :bginside => black, + :fg => lime_palette[1], + :fgtext => lime_palette[2], + :fgguide => lime_palette[2], + :fglegend => lime_palette[2], + :palette => expand_palette(black, lime_palette[1:4]), + :colorgradient => :viridis]) +) diff --git a/PlotThemes/src/orange.jl b/PlotThemes/src/orange.jl new file mode 100644 index 000000000..c57df73fa --- /dev/null +++ b/PlotThemes/src/orange.jl @@ -0,0 +1,21 @@ +#252634,#234B57,#207269,#4F9866,#9BB858,#FACF5A +# a blue/green/yellow theme of no specific origin +const orange_palette = reverse([ + colorant"#271924", # dark blue + colorant"#20545D", # semi dark blue + colorant"#32856A", # green blue + colorant"#86B15B", # green, + colorant"#FACF5A" # yellow +]) +const _black = orange_palette[5] + +const _orange = PlotTheme(Dict([ + :bg => _black, + :bginside => _black, + :fg => orange_palette[1], + :fgtext => orange_palette[2], + :fgguide => orange_palette[2], + :fglegend => orange_palette[2], + :palette => expand_palette(black, orange_palette[1:4]), + :colorgradient => :viridis]) +) diff --git a/PlotThemes/src/rose_pine.jl b/PlotThemes/src/rose_pine.jl new file mode 100644 index 000000000..b597560bf --- /dev/null +++ b/PlotThemes/src/rose_pine.jl @@ -0,0 +1,46 @@ +# https://rosepinetheme.com +const rose_pine_palette = [ + colorant"#524f67", # Highlight High + colorant"#31748f", # pine + colorant"#9ccfd8", # foam + colorant"#ebbcba", # rose + colorant"#f6c177", # gold + colorant"#eb6f92", # love + colorant"#c4a7e7", # Iris +] + +const rose_pine_bg = colorant"#191724" + +const _rose_pine = PlotTheme(Dict([ + :bg => rose_pine_bg, + :bginside => colorant"#1f1d2e", + :fg => colorant"#e0def4", + :fgtext => colorant"#e0def4", + :fgguide => colorant"#e0def4", + :fglegend => colorant"#e0def4", + :palette => expand_palette(rose_pine_bg, rose_pine_palette), + :colorgradient => cgrad(rose_pine_palette)]) +) + +const rose_pine_dawn_palette = [ + colorant"#907aa9", # Iris + colorant"#286983", # pine + colorant"#56949f", # foam + colorant"#cecacd", # Highlight High + colorant"#ea9d34", # gold + colorant"#d7827e", # rose + colorant"#b4637a", # love +] + +const rose_pine_dawn_bg = colorant"#faf4ed" + +const _rose_pine_dawn = PlotTheme(Dict([ + :bg => rose_pine_dawn_bg, + :bginside => colorant"#fffaf3", + :fg => colorant"#575279", + :fgtext => colorant"#575279", + :fgguide => colorant"#575279", + :fglegend => colorant"#575279", + :palette => expand_palette(rose_pine_dawn_bg, rose_pine_dawn_palette), + :colorgradient => cgrad(rose_pine_dawn_palette)]) +) diff --git a/PlotThemes/src/sand.jl b/PlotThemes/src/sand.jl new file mode 100644 index 000000000..cc3d2b9c6 --- /dev/null +++ b/PlotThemes/src/sand.jl @@ -0,0 +1,22 @@ +#inspired by flatwhite syntax theme for Atom +const sand_palette = [ + colorant"#6494ED", # blue + colorant"#73C990", # green + colorant"#E2C08D", # brown + colorant"#FF6347", # red + colorant"#2E2C29", # dark, + colorant"#4B4844" # medium +] + +const sand_bg = colorant"#F7F3EE" + +const _sand = PlotTheme(Dict([ + :bg => sand_bg, + :bginside => colorant"#E2DCD4", + :fg => colorant"#CBBFAF", + :fgtext => colorant"#725B61", + :fgguide => colorant"#725B61", + :fglegend => colorant"#725B61", + :palette => expand_palette(sand_bg, sand_palette), + :colorgradient => :dense]) +) diff --git a/PlotThemes/src/sheet.jl b/PlotThemes/src/sheet.jl new file mode 100644 index 000000000..a8456f81e --- /dev/null +++ b/PlotThemes/src/sheet.jl @@ -0,0 +1,129 @@ +const sheet_args = Dict{Symbol, Any}([ + :fglegend => plot_color(colorant"#225", 0.1), + :bglegend => plot_color(:white, 0.9), + :gridcolor => colorant"#225", + :minorgridcolor => colorant"#225", + :framestyle => :grid, + :minorgrid => true, + :linewidth => 1.2, + :markersize => 6, + :markerstrokewidth => 0]) + +#= NOTE ======================================================================== +Colors are taken from https://personal.sron.nl/~pault/ +===============================================================================# + +# ------------------------------------------------------------------------------ +# Mute +# ------------------------------------------------------------------------------ + +const mute_palette = [ # bright + colorant"#c67", # rose + colorant"#328", # indigo + colorant"#dc7", # sand + colorant"#173", # green + colorant"#8ce", # cyan + colorant"#825", # wine + colorant"#4a9", # teal + colorant"#993", # olive + colorant"#a49", # purple + colorant"#ddd", # grey +] + +const ylorbr_gradient = [ + colorant"#fefbe9", + colorant"#fcf7d5", + colorant"#f5f3c1", + colorant"#eaf0b5", + colorant"#ddecbf", + colorant"#d0e7ca", + colorant"#c2e3d2", + colorant"#b5ddd8", + colorant"#a8d8dc", + colorant"#9bd2e1", + colorant"#8dcbe4", + colorant"#81c4e7", + colorant"#7bbce7", + colorant"#7eb2e4", + colorant"#88a5dd", + colorant"#9398d2", + colorant"#9b8ac4", + colorant"#9d7db2", + colorant"#9a709e", + colorant"#906388", + colorant"#805770", + colorant"#684957", + colorant"#46353a", +] + +const _mute = PlotTheme(merge!(Dict{Symbol,Any}([ + :palette => mute_palette, + :colorgradient => reverse(ylorbr_gradient)]), + sheet_args) +) + +# ------------------------------------------------------------------------------ +# Vibrant +# ------------------------------------------------------------------------------ + +const vibrant_palette = [ # vibrant + colorant"#e73", # orange + colorant"#07b", # blue + colorant"#3be", # cyan + colorant"#e37", # magenta + colorant"#c31", # red + colorant"#098", # teal + colorant"#bbb", # grey +] + +const sunset_gradient = [ + colorant"#364b9a", + colorant"#4a7bb7", + colorant"#6ea6cd", + colorant"#98cae1", + colorant"#c2e4ef", + colorant"#eaeccc", + colorant"#feda8b", + colorant"#fdb366", + colorant"#f67e4b", + colorant"#dd3d2d", + colorant"#a50026", +] + +const _vibrant = PlotTheme(; + palette = vibrant_palette, + colorgradient = sunset_gradient, + sheet_args... +) + +# ------------------------------------------------------------------------------ +# Bright +# ------------------------------------------------------------------------------ + +const bright_palette = [ # bright + colorant"#47a", # blue + colorant"#e67", # red + colorant"#283", # green + colorant"#cb4", # yellow + colorant"#6ce", # cyan + colorant"#a37", # purple + colorant"#bbb", # grey +] + +const iridescent_gradient = [ + colorant"#ffffe5", + colorant"#fff7bc", + colorant"#fee391", + colorant"#fec44f", + colorant"#fb9a29", + colorant"#ec7014", + colorant"#cc4c02", + colorant"#993404", + colorant"#662506", +] + +const _bright = PlotTheme(merge!(Dict{Symbol,Any}([ + :palette => bright_palette, + :colorgradient => reverse(iridescent_gradient)]), + sheet_args) +) diff --git a/PlotThemes/src/solarized.jl b/PlotThemes/src/solarized.jl new file mode 100644 index 000000000..fe1d0ba93 --- /dev/null +++ b/PlotThemes/src/solarized.jl @@ -0,0 +1,43 @@ +# https://github.com/altercation/solarized +const _solarized_palette = (:red, :yellow, :blue, :green, :orange, :magenta, :violet, :cyan) + +const _solarized_colors = Dict([ + :base03 => RGB255(0, 43, 54), + :base02 => RGB255(7, 54, 66), + :base01 => RGB255(88, 110, 117), + :base00 => RGB255(101, 123, 131), + :base0 => RGB255(131, 148, 150), + :base1 => RGB255(147, 161, 161), + :base2 => RGB255(238, 232, 213), + :base3 => RGB255(253, 246, 227), + :blue => RGB255(38, 139, 210), + :orange => RGB255(203, 75, 22), + :red => RGB255(220, 50, 47), + :green => RGB255(133, 153, 0), + :yellow => RGB255(181, 137, 0), + :magenta=> RGB255(211, 54, 130), + :violet => RGB255(108, 113, 196), + :cyan => RGB255(42, 161, 152) +]) + +const _solarized = PlotTheme(Dict([ + :bg => _solarized_colors[:base03], + :bginside => _solarized_colors[:base02], + :fg => _solarized_colors[:base00], + :fgtext => _solarized_colors[:base01], + :fgguide => _solarized_colors[:base01], + :fglegend => _solarized_colors[:base01], + :palette => expand_palette(_solarized_colors[:base03], [_solarized_colors[c] for c in _solarized_palette]), + :colorgradient => :YlOrRd]) +) + +const _solarized_light = PlotTheme(Dict([ + :bg => _solarized_colors[:base3], + :bginside => _solarized_colors[:base2], + :fg => _solarized_colors[:base0], + :fgtext => _solarized_colors[:base1], + :fgguide => _solarized_colors[:base1], + :fglegend => _solarized_colors[:base1], + :palette => expand_palette(_solarized_colors[:base3], [_solarized_colors[c] for c in _solarized_palette]), + :colorgradient => cgrad(:YlOrRd, rev = true)]) +) diff --git a/PlotThemes/src/wong.jl b/PlotThemes/src/wong.jl new file mode 100644 index 000000000..df3a956b7 --- /dev/null +++ b/PlotThemes/src/wong.jl @@ -0,0 +1,21 @@ +# colors chosen by according to https://www.nature.com/articles/nmeth.1618?WT.ec_id=NMETH-201106 +# as proposed by @tpoisot in https://github.com/JuliaPlots/Plots.jl/issues/1144 +const wong_palette = [ + RGB(([230, 159, 0] / 255)...), # orange + RGB(([ 86, 180, 233] / 255)...), # sky blue + RGB(([ 0, 158, 115] / 255)...), # blueish green + RGB(([240, 228, 66] / 255)...), # yellow + RGB(([ 0, 114, 178] / 255)...), # blue + RGB(([213, 94, 0] / 255)...), # vermillion + RGB(([204, 121, 167] / 255)...), # reddish purple + ] + +const _wong = PlotTheme(Dict([ + :palette => expand_palette(colorant"white", wong_palette; lchoices = [57], cchoices = [100]), + :colorgradient => cgrad(:viridis).colors]) +) + +const _wong2 = PlotTheme(Dict([ + :palette => expand_palette(colorant"white", [RGB(0,0,0); wong_palette]; lchoices = [57], cchoices = [100]), + :colorgradient => :viridis]) +) diff --git a/PlotThemes/test/runtests.jl b/PlotThemes/test/runtests.jl new file mode 100644 index 000000000..08431a48d --- /dev/null +++ b/PlotThemes/test/runtests.jl @@ -0,0 +1,4 @@ +using PlotThemes +using Test, PlotUtils + +@test in(:sand, keys(PlotThemes._themes))