# How can I plot piece-wise defined function in some easily-accessed open-source tool?

I want to plot

$$f_{n}(x) = \begin{cases} x-n & \text{for } n \leq x \leq n+1 \\ 2-x+n & \text{for } n+1\leq x \leq n+2 \\ 0 & \text{otherwise.} \end{cases}$$

How can I plot a piecewise function like this one using open-source software?

• Question is not in line with objective of this site. However, how about using python or Octave (similar to Matlab)? Feb 2 '12 at 9:28
• ...how about trying to look for a system that has the Iverson bracket implemented? Feb 3 '12 at 3:28
• Isn't this just your question Is there any open-source or easy-to-access software that can... with a different example problem? Feb 6 '12 at 14:10

#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt

def fun (n, x):
if n <= x <= n + 1:
return float(x) - n
elif n + 1 <= x <= n + 2:
return 2.0 - x + n
return 0.0

vfun = np.vectorize(fun)

x = np.linspace(0, 10, 1000)
y = vfun(3, x)

plt.plot(x, y, '-')
plt.show()

• It may be worth adding that vectorize is playing a critical role here in making this to work at all (otherwise the boolean comparisons do not make sense). I should also mention that the all the computational advantages of vectorizing are lost with it (it is after all, essentially a for loop in disguise). Nov 27 '17 at 10:02

If you just want to visualize your data, you may try exporting it in a text file to visualize it with gnuplot. For your simple example, you may try to plot it in gnuplot directly as in this example.

In Matlab/Octave, if you have your function as pairs of data x1/y1 and x2/y2, you can plot them using plot( x1 , y1 , x2 , y2 ).

Another option would be to use the matplotlib package in Python. You can create a function f(n, x) that evaluates the function rather easily, and then evaluate it for a set of points. The resulting plot commands are very MATLAB-like, so if you know MATLAB, the work in matplotlib will be quite easy.

If you're a student, you can get a free, easy-to-install academic version of Python with NumPy, matplotlib, and a whole bunch of other packages pre-installed via the Enthought Python Distribution. It's quite useful, and takes out a lot of the guesswork in terms of installing the core Python packages.

• I would point out that almost everything in EPD is available at no cost through other distribution channels, whether you're a student or not. As far as I can tell, what you get from Enthought is the convenience of not having to install the packages individually, plus perhaps the benefits of linking Numpy against MKL. If you use Windows, I can see how this convenience would be useful, but on a Linux system the package manager makes it pretty easy to install the packages manually yourself. Feb 2 '12 at 20:27
• I was trying to address directly the "easily-accessed" criterion. Of course you get more custom control by doing it yourself, but for students just getting started out on Windows or Mac platforms, it's not a bad initial step. Feb 3 '12 at 8:34
• Enthought also has a free version which, while less complete, has everything you need for this problem. Enthought's libraries are usually substantially more up-to-date then you tend to find in other software distribution systems. Feb 5 '12 at 16:06
• @MRocklin: If you're a student, the "full" version is also free via their academic license. Feb 5 '12 at 21:14

SymPy is able to plot your piecewise function:

from sympy import *
x = Symbol('x')
n = 2 # you have to choose some explicit number for n
f = Piecewise((0, n<=x), (x-n, x<=n+1), (2-x+n, x<=n+1), (0, True))
plot(f)

• Does this code work in SymPy 0.7.1? I tried it with SymPy 0.6.7 and ran into errors when I tried to plot the piecewise function. Feb 5 '12 at 16:42

I think a piecewise function is a perfect case for using a closure. This frees you from the need of having a cumbersome n as an argument.

import numpy as np
import matplotlib.pyplot as plt

def define_fn(n):
def fn(x):
if n <= x <= n + 1:
return float(x) - n
elif n + 1 <= x <= n + 2:
return 2.0 - x + n
else:
return 0.0
return fn

f3 = define_fn(3)
f8 = define_fn(8)

X = np.linspace(0, 12, 1000)
Y3 = [f3(x) for x in X]
Y8 = [f8(x) for x in X]
plt.plot(X, Y3, label='f3')
plt.plot(X, Y8, label='f8')
plt.legend()
plt.show()

$$$$
`

If you don't really require it to be open-source, nor a program, then you can try Wolfram Alpha.