# Plots weird problem plotting a piecewise function at discontinuity points

**URL:** <https://discourse.julialang.org/t/plots-weird-problem-plotting-a-piecewise-function-at-discontinuity-points/102811>\
**Category:** Visualization\
**Tags:** math, plots\
**Created:** [August 15, 2023, 2:32am UTC](https://discourse.julialang.org/t/plots-weird-problem-plotting-a-piecewise-function-at-discontinuity-points/102811 "2023-08-15T02:32:23Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)\
**Post date:** [August 15, 2023, 2:32am UTC](https://discourse.julialang.org/t/plots-weird-problem-plotting-a-piecewise-function-at-discontinuity-points/102811/1 "2023-08-15T02:32:23Z")

</div>

```julia
using Plots;
g_k =0.0:0.01:10.0;
A1=1.0; A2=2.0; α=0.33;
κ2 =3.0;
κ̂2 = κ2 / (1.0 - ((A1/A2)^(1/α))); #3.41842
function f3p(k)
    if (k < κ̂2)
        return α*A1*(k^(α - 1.0))
    elseif (k > κ̂2)
        return α*A2*(( max(0.0, k - κ2) )^(α- 1.0))
    end    
end
plot(g_k, f3p)

```

Gives

 ![image](https://global.discourse-cdn.com/julialang/original/3X/0/c/0c2f11a377537c78b6e0eebf5b8500e72e1e9cab.png)  
The weird looking vertical line at the discontinuity at 3.41842 should not be there.  
How can I remove it?

---

<div class="post-metadata">

**Author:** ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)\
**Post date:** [August 15, 2023, 4:49am UTC](https://discourse.julialang.org/t/plots-weird-problem-plotting-a-piecewise-function-at-discontinuity-points/102811/2 "2023-08-15T04:49:37Z")

</div>

My only hack is to do it manually, but that’s not a good solution for more complicated problems

```julia
plot!(0.0:0.01:κ̂2, f3p, lab="f'(k)", c=1, lw=1)
plot!(κ̂2:0.01:10, f3p, lab="f'(k)", c=1, lw=1)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/3/2/32b60dbbbc9f6a0a67203d061d21ea53aac6230e.png)

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [August 15, 2023, 5:34am UTC](https://discourse.julialang.org/t/plots-weird-problem-plotting-a-piecewise-function-at-discontinuity-points/102811/3 "2023-08-15T05:34:16Z")

</div>

Well I don’t think there is an easy solution for exactly what you propose. `plot` essentially just takes 2 arrays of `x` and `y` coordinates and draws lines between them. How should it know which line to omit?

Some other ideas:

1. Instead of using two plot calls you can mark the jump with the value NaN. IIRC NaNs break the line. So your picewise function could return NaN exactly at the jump (or a small neighbourhood) and if your are plotting enoigh points such that one of them is inside that window, then it should work out.
2. Instead of `plot`/`plot!` you could use `scatter`/`scatter!` which just draws dots at the given location. If you play a bit with markersize and number of points you probably can get something reasonable as well.
3. Maybe there is a package for piecewise functions that can help you?

---

<div class="post-metadata">

**Author:** ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)\
**Post date:** [August 15, 2023, 6:08am UTC](https://discourse.julialang.org/t/plots-weird-problem-plotting-a-piecewise-function-at-discontinuity-points/102811/4 "2023-08-15T06:08:57Z")

</div>

Scatter() looks way too weird.  
Here is a more minimal/parsimonious MWE

```julia
using Plots;
grid= 0.0:0.0001:1.0
g(x)= (x<0.5) ? (x) : (x-0.5)
plot(grid, g)
scatter!(grid, g)

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/2/c/2c0a928720f281368e5660774fb3c111a3ddad74.png)

I’m hoping for some kind of options to ignore discontinuities.

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [August 15, 2023, 6:18am UTC](https://discourse.julialang.org/t/plots-weird-problem-plotting-a-piecewise-function-at-discontinuity-points/102811/5 "2023-08-15T06:18:17Z")

</div>

Yes you’ll need to play with some setting to make `scatter` look better. Did you try e.g. with `color=:blue, markersize=0.25` or something like that? I am on mobile and can’t play with these settings myself.

Edit: You probably want to disable the border (black line) around the markers. You can try `markerstrokewidth=0` for that.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [August 15, 2023, 6:32am UTC](https://discourse.julialang.org/t/plots-weird-problem-plotting-a-piecewise-function-at-discontinuity-points/102811/6 "2023-08-15T06:32:06Z")

</div>

It would probably make sense to use the information about the intervals that you have, by incorporating them into a type for which you can make a recipe which then makes gaps at the correct places. If you just have a blackbox function outputting numbers, you cannot really know whether two adjacent points are separated by a singularity or not, could always be continuous on a very small scale I guess?

---

<div class="post-metadata">

**Author:** ![DanielVandH](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielvandh/32/31134_2.png) [@DanielVandH](https://discourse.julialang.org/u/DanielVandH)\
**Post date:** [August 15, 2023, 8:25am UTC](https://discourse.julialang.org/t/plots-weird-problem-plotting-a-piecewise-function-at-discontinuity-points/102811/7 "2023-08-15T08:25:16Z")

</div>

As @jules mention, since this is just some blackbox you would need to provide it yourself with your own recipe, or break it into NaNs. `scatter` is probably okay too. Here’s one other approach you could take, identifying singularities by large slopes:

```julia
using Plots
function fix_singularities(y, x; slope_tol=100)
    _x = similar(x, 0)
    _y = similar(y, 0)
    for i in firstindex(y):(lastindex(y)-1)
        yᵢ, yᵢ₊₁ = y[i], y[i+1]
        xᵢ, xᵢ₊₁ = x[i], x[i+1]
        slope = (yᵢ₊₁ - yᵢ) / (xᵢ₊₁ - xᵢ)
        if abs(slope) < slope_tol
            push!(_x, x[i])
            push!(_y, y[i])
        else
            push!(_x, x[i], (x[i] + x[i+1]) / 2)
            push!(_y, y[i], NaN)
        end
    end
    return _y, _x
end
g(x) = (x < 0.5) ? (x) : (x - 0.5)
x = 0.0:0.0001:1.0
y = g.(x)
_y, _x = fix_singularities(y, x)
plot(_x, _y) 

```

 ![01cb465c1a053dbbbe6591bcb369ebda](https://global.discourse-cdn.com/julialang/original/3X/b/8/b80688ccb8c2445ef1cb728cf0e14409de62b4bb.png)

Maybe this is robust enough for your use case, if you are willing to recompute the `x` and `y` like this (you can of course define your own method for providing a function and a grid still).

---

<div class="post-metadata">

**Author:** ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)\
**Post date:** [August 15, 2023, 8:34am UTC](https://discourse.julialang.org/t/plots-weird-problem-plotting-a-piecewise-function-at-discontinuity-points/102811/8 "2023-08-15T08:34:30Z")

</div>

Thanks.  
I was wrong to call it a singularity.  
I meant discontinuity.

And I STRONGLY believe a good plotting package should have a `fixdiscontinuity` option.  
Just b/c others don’t do it, doesn’t mean we shouldn’t try.

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [August 15, 2023, 9:59am UTC](https://discourse.julialang.org/t/plots-weird-problem-plotting-a-piecewise-function-at-discontinuity-points/102811/9 "2023-08-15T09:59:40Z")

</div>

Random thought: Maybe Autodiff could identify true discontinuities? Just computing a local gradient does of course not contain this information. I am not too familiar with how all of these different packages work, but maybe one of the approaches could detect when there is a switch to a different code branch or just know due to code analysis when a jump occurs.

---

<div class="post-metadata">

**Author:** ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)\
**Post date:** [August 15, 2023, 3:54pm UTC](https://discourse.julialang.org/t/plots-weird-problem-plotting-a-piecewise-function-at-discontinuity-points/102811/10 "2023-08-15T15:54:57Z")

</div>

Mathematica plots discontinuous functions correctly

 ![image](https://global.discourse-cdn.com/julialang/original/3X/d/7/d77ee54c694905858e9489a41e95bbc31255919d.png)

---

<div class="post-metadata">

**Author:** ![abraemer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abraemer/32/51403_2.png) [@abraemer](https://discourse.julialang.org/u/abraemer)\
**Post date:** [August 15, 2023, 4:00pm UTC](https://discourse.julialang.org/t/plots-weird-problem-plotting-a-piecewise-function-at-discontinuity-points/102811/11 "2023-08-15T16:00:10Z")

</div>

Yes but this quite different from plotting values from a blackbox. In principle you could define a type in Julia that representa a piecewise function and define a plotting recipe that handles the discontinuity.

---

<div class="post-metadata">

**Author:** ![Albert\_Zevelev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albert_zevelev/32/11844_2.png) [@Albert\_Zevelev](https://discourse.julialang.org/u/Albert_Zevelev)\
**Post date:** [August 15, 2023, 4:05pm UTC](https://discourse.julialang.org/t/plots-weird-problem-plotting-a-piecewise-function-at-discontinuity-points/102811/12 "2023-08-15T16:05:19Z")

</div>

No!  
I had no idea my original function was discontinuous or where the discontinuity points were

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [August 15, 2023, 6:56pm UTC](https://discourse.julialang.org/t/plots-weird-problem-plotting-a-piecewise-function-at-discontinuity-points/102811/13 "2023-08-15T18:56:31Z")

</div>

Some simple approach based on the derivative and on dense sampling (try also the `tan()` case):

```julia
using Statistics, Plots; gr(dpi=600)

A1 = 1.0; A2 = 2.0; α = 0.33
κ2 = 3.0
κ̂2 = κ2 / (1.0 - ((A1/A2)^(1/α))); # 3.41842

f3p(k) = (k < κ̂2) ? α*A1*(k^(α - 1.0)) : α*A2*((max(0.0, k - κ2))^(α- 1.0))
# f3p(k) = tan(k) # try this too!

N = 1000 # the higher/denser the sampling the better
k = range(0, 10, N)
g_k = f3p.(k)

δk = [diff(g_k); 0]
dp = abs.(δk[2:end-1])
ϵ = N * median(dp) # discontinuity threshold
ix = [false; dp .> ϵ; false]
g_k[ix] .= NaN

plot(k, g_k)

```

---

<div class="post-metadata">

**Author:** ![tomaklutfu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomaklutfu/32/2411_2.png) [@tomaklutfu](https://discourse.julialang.org/u/tomaklutfu)\
**Post date:** [August 15, 2023, 7:34pm UTC](https://discourse.julialang.org/t/plots-weird-problem-plotting-a-piecewise-function-at-discontinuity-points/102811/14 "2023-08-15T19:34:05Z")

</div>

The said functions in Mathematica is not the same thing as in Plots.jl. Mathematica knows it is defined piecewise (because of its symbolic nature) and does not assume continuity whereas, in Plots.jl, it is always numeric and it almost never knows it’s symbolic structure unless a recipe with a custom type defines piecewise function structure. Hence, like Matlab and several other plotting libraries, discontinuities in the lines of plot are inferred by `NaN` values.
