Merge pull request #2657 from mileslucas/climsfunc

allow passing a function to `clims`
This commit is contained in:
Daniel Schwabeneder 2020-05-05 08:18:07 +02:00 committed by GitHub
commit 3273a65889
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 19 deletions

View File

@ -104,7 +104,7 @@ const _arg_desc = KW(
:legendtitlefontrotation => "Real. Font rotation of the legend title",
:legendtitlefontcolor => "Color Type. Font color of the legend title",
:colorbar => "Bool (show the colorbar?) or Symbol (colorbar position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:legend` (matches legend value) (note: only some may be supported in each backend)",
:clims => "`:auto` or NTuple{2,Number}. Fixes the limits of the colorbar.",
:clims => "`:auto`, NTuple{2,Number}, or a function that takes series data in and returns NTuple{2,Number}. Fixes the limits of the colorbar.",
:legendfont => "Font. Font of legend items.",
:legendtitlefont => "Font. Font of the legend title.",
:annotations => "(x,y,text) tuple(s). Can be a single tuple or a list of them. Text can be String or PlotText (created with `text(args...)`) Add one-off text annotations at the x,y coordinates.",

View File

@ -410,44 +410,46 @@ xlims(sp_idx::Int = 1) = xlims(current(), sp_idx)
ylims(sp_idx::Int = 1) = ylims(current(), sp_idx)
zlims(sp_idx::Int = 1) = zlims(current(), sp_idx)
# These functions return an operator for use in `get_clims(::Seres, op)`
process_clims(lims::NTuple{2,<:Number}) = (zlims -> ifelse.(isfinite.(lims), lims, zlims)) ignorenan_extrema
process_clims(s::Union{Symbol,Nothing,Missing}) = ignorenan_extrema
# don't specialize on ::Function otherwise python functions won't work
process_clims(f) = f
function get_clims(sp::Subplot)
function get_clims(sp::Subplot, op=process_clims(sp[:clims]))
zmin, zmax = Inf, -Inf
for series in series_list(sp)
if series[:colorbar_entry]
zmin, zmax = _update_clims(zmin, zmax, get_clims(series)...)
zmin, zmax = _update_clims(zmin, zmax, get_clims(series, op)...)
end
end
clims = sp[:clims]
if is_2tuple(clims)
isfinite(clims[1]) && (zmin = clims[1])
isfinite(clims[2]) && (zmax = clims[2])
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
function get_clims(sp::Subplot, series::Series)
function get_clims(sp::Subplot, series::Series, op=process_clims(sp[:clims]))
zmin, zmax = if series[:colorbar_entry]
get_clims(sp)
get_clims(sp, op)
else
get_clims(series)
end
clims = sp[:clims]
if is_2tuple(clims)
isfinite(clims[1]) && (zmin = clims[1])
isfinite(clims[2]) && (zmax = clims[2])
get_clims(series, op)
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)
end
function get_clims(series::Series)
"""
get_clims(::Series, op=Plots.ignorenan_extrema)
Finds the limits for the colorbar by taking the "z-values" for the series and passing them into `op`,
which must return the tuple `(zmin, zmax)`. The default op is the extrema of the finite
values of the input.
"""
function get_clims(series::Series, op=ignorenan_extrema)
zmin, zmax = Inf, -Inf
z_colored_series = (:contour, :contour3d, :heatmap, :histogram2d, :surface)
for vals in (series[:seriestype] in z_colored_series ? series[:z] : nothing, series[:line_z], series[:marker_z], series[:fill_z])
if (typeof(vals) <: AbstractSurface) && (eltype(vals.surf) <: Union{Missing, Real})
zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals.surf)...)
zmin, zmax = _update_clims(zmin, zmax, op(vals.surf)...)
elseif (vals !== nothing) && (eltype(vals) <: Union{Missing, Real})
zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals)...)
zmin, zmax = _update_clims(zmin, zmax, op(vals)...)
end
end
return zmin <= zmax ? (zmin, zmax) : (NaN, NaN)