132 views (last 30 days)

When I plot a function with discontinuity points, I get a vertical line at such points, as it can be seen in this simple example:

clc;

clear all;

h=@(x) (x>=3 & x<=7).*1+(3<x & x>7).*3;

x = linspace(0,10,100);

figure(1)

plot(x,h(x));

As it can be seen, there are near vertical lines at 3 and 7.

Attempting to remedy this, I tried the following:

clc;

clear all;

h=@(x) (x>=3 & x<=7).*1+(3<x & x>7).*3;

tol=0.0001;

x1=linspace(0,3-tol,1000);

x2=linspace(3,7,1000);

x3=linspace(7+tol,10,1000);

figure(2)

plot(x1,h(x1),x2,h(x2),x3,h(x3))

The vertical lines disappear alright, but it cycles through the colors. I can fix this coloring stuff, but at this point I must ask if there is a better way to deal with this, specially because in some situations the discontinuity points are not so straight-forwardly given.

Matt J
on 21 Jan 2015

Edited: Matt J
on 21 Jan 2015

at this point I must ask if there is a better way to deal with this, specially because in some situations the discontinuity points are not so straight-forwardly given.

You will not be able to avoid searching analytically for the discontinuities. A distinction between a sharp change and a discontinuity can't be made by numerical operations on a finite number of samples of the function.

However, you can easily write your own plotting mfile that takes a list of discontinuities and automates the work you've done breaking up the plot. Below, I've done something fancy enough to handle multiple plots and to accept most of the different syntaxes of the usual plot function,

f=@(x) 2*( x>=0 );

g=@(x) sign(x-1).*exp((x-1));

t=linspace(-2,2,2001);

figure

myplot([0,1],t,f(t),'r--', t,g(t),'b-')

and here's the generalized plotting function that it calls.

function myplot(discontinuities, varargin)

%Same as plot(), except that first argument is a list of

%discontinuities. No line joining across these discontinuities will

%appear in the plot

%

%

if nargin<3 || ~isnumeric(varargin{2})

varargin=[{1:length(varargin{1})}, varargin];

end

d=[-inf;discontinuities(:);inf];

intervals=[d(1:end-1), d(2:end)];

N=length(intervals);

idx=find(diff(cellfun(@isnumeric,varargin))==0);

M=length(idx);

for i=1:N

args=varargin;

for j=idx

xdata=args{j};

cut = xdata<=intervals(i,1) | xdata>=intervals(i,2);

args{j}(cut)=nan;

args{j+1}(cut)=nan;

end

plot(args{:}); hold on

end

hold off

Sign in to comment.

Jit
on 4 Apr 2016

If you know where the discontinuities are, you can separate them with NaNs. I have to do this to mark bad data in time-series analysis, matlab will plot the line as separated segments.

figure

time = 0:0.1:2;

freq = 2;

time = 0:0.01:2;

data = sin(2*pi*freq*time);

subplot(2,1,1);

plot(time,data);

grid on; grid minor;

ind_bad = [50:100];

data(ind_bad) = NaN;

subplot(2,1,2);

plot(time,data);

grid on; grid minor;

Sign in to comment.

Zoltán Csáti
on 21 Jan 2015

Sign in to comment.

Matt J
on 21 Jan 2015

Edited: Matt J
on 21 Jan 2015

Another option is simply to plot without joining the points. If your sampling is dense enough, the continuous parts of the locus will still look as though they are joined. Compare the red and blue curves:

g=@(x) sign(x-1).*exp((x-1));

t=linspace(-2,2,2001);

plot(t,g(t),'r*', t,g(t),'b-')

Sign in to comment.

Sign in to answer this question.

Opportunities for recent engineering grads.

Apply Today
## 2 Comments

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/170866-how-to-avoid-a-vertical-line-at-discontinuity-point#comment_261601

⋮## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/170866-how-to-avoid-a-vertical-line-at-discontinuity-point#comment_261601

## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/170866-how-to-avoid-a-vertical-line-at-discontinuity-point#comment_261613

⋮## Direct link to this comment

https://www.mathworks.com/matlabcentral/answers/170866-how-to-avoid-a-vertical-line-at-discontinuity-point#comment_261613

Sign in to comment.