From 79ce34a7122b6383ea3ca0dc0531e0a7a11d54c8 Mon Sep 17 00:00:00 2001 From: Andy Nowacki Date: Thu, 19 Aug 2021 15:22:02 +0100 Subject: [PATCH] Plotly: Enable specified contour values for ranges; warn otherwise Plotly does not support arbitrary contour values, but can plot specific contours if they are an equally-spaced range. This commit implements the plotting of contours if the `levels` keyword argument is passed an `AbstractRange`, or if a set of arbitrary values are passed. In the latter case, however, since this is not supported by Plotly, a range based on the first and last values of the collection passed in is created and used to define the contours. A warning is then issued to the user. Otherwise, any other types are assumed to be number-like and adjusted as previously. Note that Plotly does not guarantee the exact number of contours will be used. This partly addresses #3356. See https://github.com/plotly/plotly.js/issues/4503 (Plotly issue tracking the ability to set arbitrary contours). --- src/backends/plotly.jl | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 8a47fc1b..83ef2d00 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -617,11 +617,34 @@ function plotly_series(plt::Plot, series::Series) filled = isfilledcontour(series) plotattributes_out[:type] = "contour" plotattributes_out[:x], plotattributes_out[:y], plotattributes_out[:z] = x, y, z - plotattributes_out[:ncontours] = series[:levels] + 2 plotattributes_out[:contours] = KW( :coloring => filled ? "fill" : "lines", :showlabels => series[:contour_labels] == true, ) + # Plotly does not support arbitrary sets of contours: + # https://github.com/plotly/plotly.js/issues/4503 + let levels = series[:levels] + if levels isa AbstractRange + plotattributes_out[:contours][:start] = first(levels) + plotattributes_out[:contours][:end] = last(levels) + plotattributes_out[:contours][:size] = step(levels) + elseif levels isa AVec + levels_range = + range(first(levels), stop = last(levels), length = length(levels)) + plotattributes_out[:contours][:start] = first(levels_range) + plotattributes_out[:contours][:end] = last(levels_range) + plotattributes_out[:contours][:size] = step(levels_range) + @warn( + "setting arbitrary contour levels with Plotly backend is not supported; " * + "use a range to set equally-spaced contours or an integer to set the " * + "approximate number of contours with the keyword `levels`. " * + "Using levels $(levels_range)" + ) + elseif isinteger(levels) + # Assume this is a number of levels + plotattributes_out[:ncontours] = levels + 2 + end + end plotattributes_out[:colorscale] = plotly_colorscale(series[:linecolor], series[:linealpha]) plotattributes_out[:showscale] = hascolorbar(sp) && hascolorbar(series)