From 224858dad5f21898be76715953ac7bf22b6f57e6 Mon Sep 17 00:00:00 2001 From: yha Date: Sun, 3 Nov 2019 19:21:26 +0200 Subject: [PATCH 1/4] Convert infinite values to NaN --- src/examples.jl | 17 +++++++++++++++++ src/series.jl | 5 ++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/examples.jl b/src/examples.jl index 19b167ad..5208b9af 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -480,6 +480,23 @@ PlotExample("Histogram2D (complex values)", end)] ), +PlotExample("Unconnected lines using NaN values", +""" +Non-finite values, including `NaN`, are not plotted. +Instead, lines are separated into segments at these values. +""", + [:(begin + x,y = [1,2,2,1,1], [1,2,1,2,1] + plot( + plot([rand(5); NaN; rand(5); NaN; rand(5)]), + plot([1,Inf,2,3], marker=true), + plot([x; NaN; x.+2], [y; NaN; y.+1], arrow=2), + plot([1, 2+3im, Inf, 4im, 3, -Inf*im, 0, 3+3im], marker=true), + legend=false + ) + end)] +), + ] # Some constants for PlotDocs and PlotReferenceImages diff --git a/src/series.jl b/src/series.jl index bbc2248f..5c0ffeac 100644 --- a/src/series.jl +++ b/src/series.jl @@ -14,7 +14,10 @@ const SeriesData = Union{AVec{<:DataPoint}, Function, Surface, Volume} prepareSeriesData(x) = error("Cannot convert $(typeof(x)) to series data for plotting") prepareSeriesData(::Nothing) = nothing -prepareSeriesData(s::SeriesData) = handlemissings(s) +prepareSeriesData(s::SeriesData) = handleinfinites(handlemissings(s)) + +handleinfinites(s) = s +handleinfinites(s::AbstractArray{<:MaybeNumber}) = [isinf(x) ? NaN : x for x in s] handlemissings(v) = v handlemissings(v::AbstractArray{<:MaybeNumber}) = replace(v, missing => NaN) From c9a9541d0edc6aa67f81e5a56fc6a0ad57bedf2b Mon Sep 17 00:00:00 2001 From: yha Date: Mon, 4 Nov 2019 03:27:47 +0200 Subject: [PATCH 2/4] Avoid second copy of data. Inf handling for surfaces and volumes. --- src/series.jl | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/series.jl b/src/series.jl index 5c0ffeac..d8c182df 100644 --- a/src/series.jl +++ b/src/series.jl @@ -10,20 +10,19 @@ const FuncOrFuncs{F} = Union{F, Vector{F}, Matrix{F}} const MaybeNumber = Union{Number, Missing} const MaybeString = Union{AbstractString, Missing} const DataPoint = Union{MaybeNumber, MaybeString} -const SeriesData = Union{AVec{<:DataPoint}, Function, Surface, Volume} prepareSeriesData(x) = error("Cannot convert $(typeof(x)) to series data for plotting") prepareSeriesData(::Nothing) = nothing -prepareSeriesData(s::SeriesData) = handleinfinites(handlemissings(s)) +prepareSeriesData(f::Function) = f +prepareSeriesData(a::AbstractArray{<:MaybeNumber}) = replace!( + x -> ismissing(x) || isinf(x) ? NaN : x, + map(float,a)) +prepareSeriesData(a::AbstractArray{<:MaybeString}) = replace(x -> ismissing(x) ? "" : x, a) +prepareSeriesData(s::Surface{<:AMat{<:MaybeNumber}}) = Surface(prepareSeriesData(s.surf)) +prepareSeriesData(s::Surface) = s # non-numeric Surface, such as an image +prepareSeriesData(v::Volume) = Volume(prepareSeriesData(v.v), v.x_extents, v.y_extents, v.z_extents) -handleinfinites(s) = s -handleinfinites(s::AbstractArray{<:MaybeNumber}) = [isinf(x) ? NaN : x for x in s] - -handlemissings(v) = v -handlemissings(v::AbstractArray{<:MaybeNumber}) = replace(v, missing => NaN) -handlemissings(v::AbstractArray{<:MaybeString}) = replace(v, missing => "") -handlemissings(s::Surface) = Surface(handlemissings(s.surf)) -handlemissings(v::Volume) = Volume(handlemissings(v.v), v.x_extents, v.y_extents, v.z_extents) +prepareSeriesArray(a::AbstractArray{<:MaybeNumber}) = [ismissing(x) || isinf(x) ? NaN : x for x in a] # default: assume x represents a single series convertToAnyVector(x, plotattributes) = Any[prepareSeriesData(x)] From 5c1c80fd9a2d56e5f45b7202330cd273df733662 Mon Sep 17 00:00:00 2001 From: yha Date: Mon, 4 Nov 2019 03:35:09 +0200 Subject: [PATCH 3/4] Remove leftover method --- src/series.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/series.jl b/src/series.jl index d8c182df..b509ab52 100644 --- a/src/series.jl +++ b/src/series.jl @@ -22,8 +22,6 @@ prepareSeriesData(s::Surface{<:AMat{<:MaybeNumber}}) = Surface(prepareSeriesData prepareSeriesData(s::Surface) = s # non-numeric Surface, such as an image prepareSeriesData(v::Volume) = Volume(prepareSeriesData(v.v), v.x_extents, v.y_extents, v.z_extents) -prepareSeriesArray(a::AbstractArray{<:MaybeNumber}) = [ismissing(x) || isinf(x) ? NaN : x for x in a] - # default: assume x represents a single series convertToAnyVector(x, plotattributes) = Any[prepareSeriesData(x)] From c3c63971ab9a9a769f53a1661c989d5727cc03b6 Mon Sep 17 00:00:00 2001 From: yha Date: Mon, 4 Nov 2019 16:20:43 +0200 Subject: [PATCH 4/4] Update NaN example to show missing values. --- src/examples.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/examples.jl b/src/examples.jl index 5208b9af..62600217 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -480,16 +480,16 @@ PlotExample("Histogram2D (complex values)", end)] ), -PlotExample("Unconnected lines using NaN values", +PlotExample("Unconnected lines using `missing` or `NaN`", """ -Non-finite values, including `NaN`, are not plotted. +Missing values and non-finite values, including `NaN`, are not plotted. Instead, lines are separated into segments at these values. """, [:(begin x,y = [1,2,2,1,1], [1,2,1,2,1] plot( plot([rand(5); NaN; rand(5); NaN; rand(5)]), - plot([1,Inf,2,3], marker=true), + plot([1,missing,2,3], marker=true), plot([x; NaN; x.+2], [y; NaN; y.+1], arrow=2), plot([1, 2+3im, Inf, 4im, 3, -Inf*im, 0, 3+3im], marker=true), legend=false