# Smoothed lines

I follow this list rather closely so I am hoping that I

> haven't missed something obvious here.

> I am trying to plot a line graph with pylab.plot. I was
> wondering if there is an easy way to plot a smoothed line
> graph like excel does by default. I could obviously apply a
> signal filter but I was wondering if there is a simple user
> friendly way to get something like excel does in matplotlb
> without the user having to know about signal processing.

It would help if you described more precisely what it is Excel does.
You may be surprised to learn that I rarely use Excel for plotting
<wink>

In general, and with a few exceptions, mpl tries to be a plotting
library, and despite some claims to the contrary, tries not to do much
magic. Automatic smoothing sounds a bit dangerous to me, and as you
say, is squarely in the realm of signal processing.

Here is a little helper function I use to generate a smoothing
functional -- it is a function that returns a function for smoothing
signals with a low pass filter.

import scipy.signal as sig

def lowbutter(lpcf, lpsf, Fs, gpass=3, gstop=15):
"""
Return a low pass butterworth filter with
lpcf : lowpass corner freq
lpsf : lowpass stop freq
gpass : corner freq attenuation
gstop : stop freq attenuation

return value is a callable function that will filter your data

Example:
mybutt = lowbutter(12, 15, eeg.freq) # pun intended
sfilt = mybutt(s1)

"""

Nyq = Fs/2.
wp = lpcf/Nyq
ws = lpsf/Nyq

ord, Wn = sig.buttord(wp, ws, gpass, gstop)
b, a = sig.butter(ord, Wn, btype='lowpass')

def func(x):
return sig.lfilter(b,a,x)
return func

I use this function like

myfilt = lowbutter(20,30,400)

and then pass myfilt off to plotting or analysis code. You could
easily write a smooth_plot. Here is a sketch of how it might go

def smooth_plot(x, y, somefilt=lowbutter(20,30,400), **kwargs):
"""
plot x versus a smoothed version of y, using callable filter
myfilt. kwargs are passed on to plot
"""
y = myfilt(y)
plot(x, y, **kwargs)

For bandpass data, the equivalent of lowbutter that I use is

def bandpass(lpsf, lpcf, hpcf, hpsf, Fs, gpass=3, gstop=20):
"""
Return a butterworth bandpass filter

lpcf : lowpass corner freq
lpsf : lowpass stop freq
hpcf : highpass corner freq
hpsf : highpass stop freq
gpass : corner freq attenuation
gstop : stop freq attenuation

return value is a callable function that will filter your data
"""

Nyq = Fs/2.
wp = [lpcf/Nyq, hpcf/Nyq]
ws = [lpsf/Nyq, hpsf/Nyq]
ord, Wn = sig.buttord(wp, ws, gpass, gstop)
b,a = sig.butter(ord, Wn, btype='bandpass') # pun intended
def func(x):
return sig.lfilter(b,a,x)

return func

I don't think there could be any consensus on a default value for
myfilt since people work in very different time scales.

A short wiki entry on the scipy web site on how to do write plotting
functions with filtering built in along the lines of the examples
above would be useful.

If you would like to write one up, with example figures, that would be
great.

> Any help would be greatly appreciated.

> And, John and company thanks for a brilliant piece of
> software.

Much obliged,
JDH