JuliaPlots / PlotlyJS.jl

Julia library for plotting with plotly.js
Other
418 stars 77 forks source link

Too many entries in colorscales defined via colors.colormapname #416

Open empet opened 2 years ago

empet commented 2 years ago

I started testing how PlotlyJS/PlotlyBase works with traces involving colorscale, set by colorscale=colors.colormapname. So far I checked uniform colormaps, such as viridis, inferno, magma, twilight, and all cmocean colormaps https://github.com/JuliaGraphics/ColorSchemes.jl/blob/master/data/cmocean.jl.

Printing the corresponding json version of the plot, I noticed that for sequential colormaps is created a plotly colorscale of 256 entries (each entry as a vector `[scale, colorcode]'), while for diverging colorscales, the number of entries is doubled to 512. Both 256 and 512 are big numbers for colorscale entries, compared with plotly.py that defines only 13 entries.

When I worked with previous PlotlyJS versions I defined a function to get a plotly colorscale of at least 11 entries as follows:

using ColorSchemes
import Colors.hex
function plotly_cs(colorscheme; n_entries=11)
    scale = LinRange(0, 1, n_entries) 
    colors = [get(colorscheme, s) for s in scale]
    return [[s, hex(color)] for (s, color) in zip(scale, colors)]
end

Example:

using PlotlyJS
f(x,y) = sin(x)^10 + cos(10 + y*x) + cos(x) + 0.2*y + 0.1*x
y  = -5:0.05:10
x = -5:0.05:5   
z= [f(s, t) for t in y, s in x]
tr = heatmap(x=x, y=y, z=z, colorscale=colors.curl, colorbar_thickness=25)
pl = plot(tr, Layout(width=400, height=400))
#savefig(pl, "heatmap_colors_curl.png", scale=1)
print(length(pl.plot.data[1].colorscale))
pl

If in the definition of the plot, pl, above, you are setting colorscale=pl_curl, where pl_curl = plotly_cs(ColorSchemes.curl), i.e.

11-element Vector{Vector{Any}}:
 [0.0, "151D44"]
 [0.1, "1C4D61"]
 [0.2, "117D79"]
 [0.3, "5EA786"]
 [0.4, "B6CBB0"]
 [0.5, "FEF6F4"]
 [0.6, "E6B8A2"]
 [0.7, "D4786A"]
 [0.8, "AE4060"]
 [0.9, "76195D"]
 [1.0, "340D35"]

you'll get a plot indistinguishable from the initial one. I'm not very skilled in working with Julia to suggest a solution to reduce the overloading of the json file with so many, unnecesary entries in colorscales, but I'm sure that @sglyon could find one.

I also noticed that restyle!(pl, 1; colorscale=colors.balance) or setting any other coloscheme from ColorSchemes.jl, doesn't update the colorscale, as expected, but the plot is redrawn with the plotly.js default colorscale (RdBu). I also tried to use coloraxis and relayout! and again the coloraxis_colorscale is not updated with the colorscale I required.

I'm running PlotlyJS.jl v 0.18.7

sglyon commented 2 years ago

Very helpful comments! I think having less colors is a really good idea to avoid unneeded bloat.

I’ll add it to my list!