I've looked in the documentation and online, and I can't seem to find
any way to do Gaussian smoothing.
Normally, I'd simply write a function for it, but the problem is that
this type of smoothing of course requires as many dimensions as there
are data points. That is, each point of data is scaled as a function
of the height of all other points. Since (I think) GNUPLOT reads one
line at a time from data files, I don't know if it's possible.
That said, GNUPLOT is so powerful, I can't see it not being able to do
something like this. Could somebody please point me in the right
direction?
Cheers,
Tim.
Gnuplot is primarily a plotting tool . This is probably the sort of
data processing task you could do externally , either before calling
gnuplot of by using gnuplot's system() command.
Having said that someone just posted a patch to do something like this
to gnuplot-beta mailing list. You may like to get current cvs
gnuplot , add that patch and test it.
BTW if you want to write some code you can do gaussian smoothing by
applying a finite kernel filter. In practice this is just a few values
depending on the width of your gaussian filter, not the all your data
points.
I don't really want to keep a lot of extra numbers around. These files
will be somewhat large and numerous, so it could become confusing very
fast.
If I write a program which outputs the smoothed data to stdout, could
I somehow run it within gnuplot and directly read the output? Not that
it's a big issue to write to a temporary file, but I would somehow
like something cleaner.
Thank you by the way, and I will definitely use a truncated (finite)
kernel.
Best regards,
Tim.
you need to look at gnuplot help command and read the plot topic.
plot '-' is a special filename that takes input from stdin.
As I was teached in this newsgroup just a few weeks ago, "plot '< myscript'"
does just that. So "plot '< smooth mydata.dat'" is probably what you want.
Lewin
Thanks, that sounds great. Exactly what I need.
Cheers,
Tim.
nonsense!
smooth option fits a spline which is absolutely nothing to do with
gaussian.
also your command in not good.
BTW past tense of teach is taught, not teached. You probably meant
learnt anyway. That's fine , you're not native English speaker, but
avoid giving bogus "help".
If you read a little higher, the question became how I can directly
read data into gnuplot from stdin without using the terminal (such
as ./myprog | gnuplot plot.plt). I'm writing my own smoothing program.
> also your command in not good.
Lewin Boehnke's command does what it is supposed to. It is 'good' for
what it does.
> BTW past tense of teach is taught, not teached. You probably meant
> learnt anyway. That's fine , you're not native English speaker, but
> avoid giving bogus "help".
That's just rude. There's no excuse for this kind of hostility, even
if his advise was wrong. You didn't read the entire post and got
yourself upset over nothing. I assume you were having a bad day.
Relax.
Regards,
Tim
strange you find it works. There are at least two errors that fail to
get past the gnuplot parser:
1. smooth requires an option modifier such as csplines , it is not
valid on its own.
2. the file name must come before all options
3. mydata.dat must be in quotes otherwise it gets read as a command
and fails
I think describing this as nonsense is justified.
> > BTW past tense of teach is taught, not teached. You probably meant
> > learnt anyway. That's fine , you're not native English speaker, but
> > avoid giving bogus "help".
>
> That's just rude. There's no excuse for this kind of hostility, even
> if his advise was wrong. You didn't read the entire post and got
> yourself upset over nothing. I assume you were having a bad day.
> Relax.
>
> Regards,
>
> Tim
BTW I did read the whole post, I even gave you valid advise on what
command does exactly what you want and refered you to the relevant
help topic. You neither acknowlege or thank me. But I won't get upset,
I'm having a good day today ;)
Maybe the other cruft got in the way and you missed my post.
greets.
Reading the context of my post, you should realize that "smooth" does not
refer to any gnuplot keyword (I was not aware there is such keyword,
otherwise I would of course have chosen an other word in my post) but to
an -yet to be written- external script smoothing the data in mydata.dat.
At the latest you should have realized that when you saw that smooth is
_inside_ the quotes, which can by no means refer to any gnuplot keyword!
Lewin Boehnke
OK, well you had the whole thing in double quotes as well so the
syntax could not be taken too literally. Your not knowing smooth was a
key word added to the confusion.
plot "< ./gaussian.sh datafile.dat"
will indeed read from stdin on unix/linux as documented in help load
and help batch.
Sorry my comments were harsher than necessary.
I guess we're all friends again :) Thanks to all of you... even
goog...@catking.net :P
I wanted to give this follow-up post. I'm sure I'm not the only one
who has wanted to do some gaussian smoothing. I wrote this last week.
I haven't had a chance to comment it much, but I think it's straight
forward. It's written in C, and should be portable (don't forget -lm
for the math library).
It takes command line arguments of the standard deviation and kernel
radius (in that order). The standard deviation can be any floating
point value, but the kernel radius should be integral. The kernel
radius should be 3-5 times the standard deviation in order to preserve
the normality of the convolution, but keep in mind that the kernel
radius will be shaved off of the end of the data, since there is no
way to preserve normality at the boundary. One could easily program in
some boundary conditions (reflectance... or trickier... periodicity).
Anyhow, here is the code. I hope it helps someone:
// gsmooth.c
//
// Author: Timothy A.V. Teatro <timothy...@uoit.ca>
// Date : May 30, 2008
//
// Description:
// This program reads data from standard in and convoludes it with a
// discretized Gaussian lineshape. The output is sent to stdout and
// error reporting is minimal as the program is intended to be read
// directly by GNUPLOT.
//
// EDIT: This version is simplified for general use; to be posted on
// comp.graphics.apps.gnuplot
//
// Usage: ./gsmooth sigma krad < data.dat
// sigma is the standard deviation of the Gaussian kernel:
// g(x) = exp( -x^2/(2*sigma^2) ) / (2pi)^1/2 sigma
// and krad is the radius of the kernel, in datapoints. That is,
// over what radius the "averaging" is going to occur. In order to
// preserve normality, krad should not be less than three times the
// standard deviation.
//
// Usage within gnuplot is shown in the following example:
//> #set term post monochrome
//> #set output "plotroughsmooth.ps"
//>
//> #unset key
//>
//> plot 'in.dat' using 1:2 title "Noise" w l, \
//> '< gsmooth 2.00 7 < in.dat' using 1:2 title "Smoothed:
sig=2.00" w l
//
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double ReadDouble(FILE*file,char*flag);
double smoothY(double Y[], double kernel[], int krad);
int main(int argc, char *argv[]) {
double sigma, *kernel, scale;
double *X, *Y;
int krad, i;
char End;
//
// Parse Commandline arguments. We get the Standard Deviation
// and the kernel size.
//
sigma = atof(argv[1]);
krad = atoi(argv[2]);
//
// Now initialize the kernel
//
// Create the space in memory:
//
kernel=(double *)malloc( sizeof(double[2*krad+1]) );
//
// Define the scaling factor. Since exp(0)=1, we also assign the
value
// of scale to the center point (x=mu) in the kernel.
//
scale = 1/(sqrt(2*M_PI)*sigma);
kernel[krad] = scale;
//
// Now define the rest of the kernal, symmetrically about the
center.
//
for (i=0; i<=krad-1; i++) {
kernel[i]=scale*exp( -(i-krad)*(i-krad)/(2*sigma*sigma) );
kernel[krad*2-i]=kernel[i];
//ec printf("kernel[%d] = %f\n", i, kernel[i]);
//ec printf("kernel[%d] = %f\n\n", krad*2-i, kernel[krad*2-i]);
}
//ec for (i=0; i<=krad*2; i++) {
//ec printf("%d %f\n", i-krad, kernel[i]);
//ec }
//
// Now that the kernel is defined, we can start reading in data.
// We must read ahead of our calculation by krad entries.
//
//
// Start by allocating space for the coordinates.
//
X = (double *) malloc( sizeof(double[2*krad+1]) );
Y = (double *) malloc( sizeof(double[2*krad+1]) );
//
// Read off the first kernel diameter.
//
for (i=0; i<=2*krad; i++) {
if (End == EOF) break;
X[i] = ReadDouble(stdin, &End);
Y[i] = ReadDouble(stdin, &End);
}
do {
printf("%f\t%f\n", X[krad], smoothY(Y, kernel, krad));
for (i=0; i<=2*krad-1; i++) {
X[i]=X[i+1];
Y[i]=Y[i+1];
}
X[2*krad] = ReadDouble(stdin, &End);
Y[2*krad] = ReadDouble(stdin, &End);
} while (End != EOF);
return 0;
}
double ReadDouble(FILE*file,char*flag)
{
char number[15];
double Num;
int i=0;
char ch;
do
{
ch = fgetc(file);
if(ch!=' ' && ch!='\t' && ch!='\n' && ch!=EOF)
{
do
{
number[i]=ch;
i++;
ch = fgetc(file);
}while(ch!=' ' && ch!='\t' && ch!='\n' && ch!=EOF);
break;
}
} while (ch != EOF);
*flag=ch;
number[i]='\0';
Num=atof(number);
return Num;
}
double smoothY(double Y[], double kernel[], int krad) {
int i;
double G=0.;
for (i=0; i<=krad * 2; i++) {
G += Y[i] * kernel[i];
}
return G;
}