Escolher um conjunto apropriado de cores ou barra de cores para sua plotagem é uma parte essencial para apresentação de resultados. Colors.jl é suportado em Makie.jl
para que você possa usar cores nomeadas ou passar valores RGB
ou RGBA
. Além disso, os mapas de cores ColorSchemes.jl e PerceptualColourMaps.jl também podem ser usados. Vale a pena saber que você pode reverter um mapa de cores fazendo Reverse(:colormap_name)
para obter uma cor transparente ou mapa de cores com color=(:red,0.5)
e colormap=(:viridis, 0.5)
.
Diferentes casos de uso serão mostrados a seguir. Então vamos definir um tema personalizado com novas cores e uma paleta de cores.
Por padrão Makie.jl
tem um conjunto predefinido de cores para percorrê-las automaticamente. Conforme mostrado nas figuras anteriores, onde nenhuma cor específica foi definida. A substituição desses padrões é feita chamando a palavra-chave color
na função de plotagem e especificando uma nova cor por meio de um Symbol
ou String
. Veja isso em ação no exemplo a seguir:
function set_colors_and_cycle()
# Epicycloid lines
x(r, k, θ) = r * (k .+ 1.0) .* cos.(θ) .- r * cos.((k .+ 1.0) .* θ)
y(r, k, θ) = r * (k .+ 1.0) .* sin.(θ) .- r * sin.((k .+ 1.0) .* θ)
θ = LinRange(0, 6.2π, 1000)
axis = (; xlabel=L"x(\theta)", ylabel=L"y(\theta)",
title="Epicycloid", aspect=DataAspect())
figure = (; resolution=(600, 400), font="CMU Serif")
fig, ax, _ = lines(x(1, 1, θ), y(1, 1, θ); color="firebrick1", # string
label=L"1.0", axis=axis, figure=figure)
lines!(ax, x(4, 2, θ), y(4, 2, θ); color=:royalblue1, #symbol
label=L"2.0")
for k = 2.5:0.5:5.5
lines!(ax, x(2k, k, θ), y(2k, k, θ); label=latexstring("$(k)")) #cycle
end
Legend(fig[1, 2], ax, latexstring("k, r = 2k"), merge=true)
fig
end
set_colors_and_cycle()
Onde, nas duas primeiras linhas, usamos a palavra-chave color
para especificar nossa cor. O resto está usando o padrão do conjunto de cores do ciclo. Mais tarde, aprenderemos como fazer um ciclo personalizado.
Em relação aos mapas de cores, já estamos familiarizados com a palavra-chave colormap
para heatmap
s e scatter
s. Aqui, mostramos que um mapa de cores também pode ser especificado por meio de um Symbol
ou uma String
, semelhante a cores. Ou até mesmo um vetor de cores RGB
. Vamos fazer nosso primeiro exemplo chamando mapas de cores como Symbol
, String
e cgrad
para valores categóricos. Cheque ?cgrad
para mais informações.
figure = (; resolution=(600, 400), font="CMU Serif")
axis = (; xlabel=L"x", ylabel=L"y", aspect=DataAspect())
fig, ax, pltobj = heatmap(rand(20, 20); colorrange=(0, 1),
colormap=Reverse(:viridis), axis=axis, figure=figure)
Colorbar(fig[1, 2], pltobj, label = "Reverse colormap Sequential")
fig
Ao definir um colorrange
geralmente os valores fora deste intervalo são coloridos com a primeira e a última cor do mapa de cores. No entanto, às vezes é melhor especificar a cor desejada em ambas as extremidades. Fazemos isso com highclip
e lowclip
:
using ColorSchemes
figure = (; resolution=(600, 400), font="CMU Serif")
axis = (; xlabel=L"x", ylabel=L"y", aspect=DataAspect())
fig, ax, pltobj=heatmap(randn(20, 20); colorrange=(-2, 2),
colormap="diverging_rainbow_bgymr_45_85_c67_n256",
highclip=:black, lowclip=:white, axis=axis, figure=figure)
Colorbar(fig[1, 2], pltobj, label = "Diverging colormap")
fig
Mas mencionamos que também vetores RGB
são opções válidas. Para o nosso próximo exemplo, você pode passar o mapa de cores personalizado perse ou usar cgrad
para forçar um Colorbar
categórico.
using Colors, ColorSchemes
figure = (; resolution=(600, 400), font="CMU Serif")
axis = (; xlabel=L"x", ylabel=L"y", aspect=DataAspect())
cmap = ColorScheme(range(colorant"red", colorant"green", length=3))
mygrays = ColorScheme([RGB{Float64}(i, i, i) for i in [0.0, 0.5, 1.0]])
fig, ax, pltobj = heatmap(rand(-1:1, 20, 20);
colormap=cgrad(mygrays, 3, categorical=true, rev=true), # cgrad and Symbol, mygrays,
axis=axis, figure=figure)
cbar = Colorbar(fig[1, 2], pltobj, label="Categories")
cbar.ticks = ([-0.66, 0, 0.66], ["-1", "0", "1"])
fig
Por fim, os tiques na barra de cores para o caso categorial não são centralizados por padrão em cada cor. Isso é corrigido passando ticks personalizados, como em cbar.ticks = (positions, ticks)
. A última situação é passar uma tupla de duas cores para o colormap
como símbolos, strings ou uma mistura. Você obterá um mapa de cores interpolado entre essas duas cores.
Além disso, cores codificadas em hexadecimal também são aceitas. Então, no topo do nosso mapa de calor, vamos colocar um ponto semitransparente usando:
figure = (; resolution=(600, 400), font="CMU Serif")
axis = (; xlabel=L"x", ylabel=L"y", aspect=DataAspect())
fig, ax, pltobj = heatmap(rand(20, 20); colorrange=(0, 1),
colormap=(:red, "black"), axis=axis, figure=figure)
scatter!(ax, [11], [11], color=("#C0C0C0", 0.5), markersize=150)
Colorbar(fig[1, 2], pltobj, label="2 colors")
fig
Aqui, poderíamos definir um Tema
global com um novo ciclo de cores, mas essa não é a maneira recomendada de fazer isso. É melhor definir um novo tema e usar como mostramos antes. Vamos definir um novo com um cycle
para :color
, :linestyle
, :marker
e um novo padrão colormap
. Vamos adicionar esses novos atributos ao nosso publication_theme
anterior.
function new_cycle_theme()
# https://nanx.me/ggsci/reference/pal_locuszoom.html
my_colors = ["#D43F3AFF", "#EEA236FF", "#5CB85CFF", "#46B8DAFF",
"#357EBDFF", "#9632B8FF", "#B8B8B8FF"]
cycle = Cycle([:color, :linestyle, :marker], covary=true) # alltogether
my_markers = [:circle, :rect, :utriangle, :dtriangle, :diamond,
:pentagon, :cross, :xcross]
my_linestyle = [nothing, :dash, :dot, :dashdot, :dashdotdot]
Theme(
fontsize=16, font="CMU Serif",
colormap=:linear_bmy_10_95_c78_n256,
palette=(color=my_colors, marker=my_markers, linestyle=my_linestyle),
Lines=(cycle=cycle,), Scatter=(cycle=cycle,),
Axis=(xlabelsize=20, xgridstyle=:dash, ygridstyle=:dash,
xtickalign=1, ytickalign=1, yticksize=10, xticksize=10,
xlabelpadding=-5, xlabel="x", ylabel="y"),
Legend=(framecolor=(:black, 0.5), bgcolor=(:white, 0.5)),
Colorbar=(ticksize=16, tickalign=1, spinewidth=0.5),
)
end
E aplique-o a uma função de plotagem como a seguinte:
function scatters_and_lines()
x = collect(0:10)
xh = LinRange(4, 6, 25)
yh = LinRange(70, 95, 25)
h = randn(25, 25)
fig = Figure(resolution=(600, 400), font="CMU Serif")
ax = Axis(fig[1, 1], xlabel=L"x", ylabel=L"f(x,a)")
for i in x
lines!(ax, x, i .* x; label=latexstring("$(i) x"))
scatter!(ax, x, i .* x; markersize=13, strokewidth=0.25,
label=latexstring("$(i) x"))
end
hm = heatmap!(xh, yh, h)
axislegend(L"f(x)"; merge=true, position=:lt, nbanks=2, labelsize=14)
Colorbar(fig[1, 2], hm, label="new default colormap")
limits!(ax, -0.5, 10.5, -5, 105)
colgap!(fig.layout, 5)
fig
end
with_theme(scatters_and_lines, new_cycle_theme())
Neste ponto, você deve ter controle completo sobre suas cores, estilos de linha, marcadores e mapas de cores para seus plots. A seguir, veremos como gerenciar e controlar layouts.