www.pudn.com > mixxx-1.5.0.zip > gplot3.c
/*
Copyright (c) Ed. Breen
All rights reserved.
EiC's interface to gnuplot. Ed. Breen
Example usages: just cut and paste the following
lines, one at a time, into your EiC session, but
leave out the EiC #> bit of course:
EiC 1> #include MathStats/randg.c
EiC 2> #include gnuplot/gplot.h
EiC 3> #include gnuplot/gplot3.c
EiC 4> plot_t *p1 = openPlot("p1");
EiC 5> send2plot(p1,"plot sin(x) + tan(x)");
EiC 6> int i; float f[100];
EiC 7> for(i=0;i<100;i++) f[i] = randg(50,10);
EiC 8> plotData(f,100,p1,plotFloats);
EiC 9> send2plot(p1,"f(x) = 10 * cos(x/2)+ 50; replot f(x)");
EiC 10> for(i=0;i<100;i++) f[i] = i;
EiC 11> replotData(f,100,p1,plotFloats);
EiC 12> closePlot(p1);
*/
#ifndef _POSIX_SOURCE
#define _POSIX_SOURCE
#endif
#include
#include
#include
#include
#include
#ifdef _EiC
#include "gnuplot/gplot.h"
#else
#include "gplot.h"
#endif
static float Plot_jitter = 0.01;
static int compareFloats(void const *f1, void const *f2)
{
if(*(float*)f1 > *(float*)f2)
return 1;
if(*(float*)f1 < *(float*)f2)
return -1;
return 0;
}
void Send_2_plot_(plot_t *p, char * fmt, ...)
{
char buff[1024];
va_list args;
va_start(args,fmt);
vsprintf(buff,fmt,args);
fputs(buff,getPlotFile(p));
fputc('\n',getPlotFile(p));
va_end(args);
}
void setPlotJitter(float v)
{
Plot_jitter = v;
}
float getPlotJitter(void)
{
return Plot_jitter;
}
void plotxy(float *x, float * y,int n,plot_t *p)
{
int i;
float miny,maxy,minx,maxx, xr, yr;
FILE *fp;
fp = fopen(p->fname,"w");
miny = maxy = *y;
minx = maxx = *x;
for(i=0;i maxy)
maxy = *y;
if(*x < minx)
minx = *x;
if(*x > maxx)
maxx = *x;
fprintf(fp,"%g %g\n",*x,*y);
}
fclose(fp);
xr = (maxx - minx)/n;
yr = (maxy - miny)/n;
minx -= xr;
maxx += xr;
miny -= yr;
maxy += yr;
Send_2_plot_(p,"plot [%g:%g] [%g:%g] '%s' with %s",
minx,maxx,miny,maxy,p->fname,
p->linetype);
}
float plotChars(void *xd, int idx, float *min, float *max)
{
int *id = xd;
if(id[idx] < *min)
*min = id[idx];
if(id[idx] > *max)
*max = id[idx];
return id[idx];
}
float plotInts(void *xd, int idx, float *min, float *max)
{
int *id = xd;
if(id[idx] < *min)
*min = id[idx];
if(id[idx] > *max)
*max = id[idx];
return id[idx];
}
float plotFloats(void *xd, int idx,float *min, float *max)
{
float *id = xd;
if(id[idx] < *min)
*min = id[idx];
if(id[idx] > *max)
*max = id[idx];
return id[idx];
}
void plotData(void *hist,
int n,
plot_t *p,
float pltfunc(void *xd,int idx,float *min,float *max))
{
int i;
float min = FLT_MAX,max = FLT_MIN;
FILE *fp;
fp = fopen(p->fname,"w");
for(i=0;ifname,
p->linetype);
}
void replotData(void *hist,
int n,
plot_t *p,
float pltfunc(void *xd,int idx,float *min,float *max))
{
int i;
float min = FLT_MAX,max = FLT_MIN;
FILE *fp;
char *name = tmpnam(NULL);
fp = fopen(name,"w");
for(i=0;ilinetype);
}
void replotxy(float *x, float * y,int n,plot_t *p)
{
int i;
FILE *fp;
char *name = tmpnam(NULL);
fp = fopen(name,"w");
for(i=0;ilinetype);
}
void scatPlot(plot_t *p, int n, ...)
{
/* do Line scatter plots.
* This function expects `n' arrays of
* floats.
*
* example1: scatPlot(p1,1, a1, n1);
* where
* a1 is a pointer of an array of float
* with n1 elements.
*
* example2: scatPlot(p1,2,
* a1,n1,
* a2, n2);
*
*/
va_list ap;
FILE *fp;
char buf[100];
int nX;
float *aX, min, max;
int i, j;
// float randg(float,float);
va_start (ap, n);
fp = fopen(p->fname,"w");
min = FLT_MAX;
max = FLT_MIN;
for(j=1; j <= n; j++) {
aX = va_arg(ap, float *);
nX = va_arg(ap, int );
for(i=0;i max)
max = *aX;
// fprintf(fp,"%g %g\n",j+randg(0,Plot_jitter),*aX);
}
}
fclose(fp);
sprintf(buf,"plot [0:%d] [%g:%g] '%s' with points",j,min,max,p->fname);
send2plot(p,buf);
va_end (ap);
}
void boxPlot(plot_t *p, /* plot */
int n, /* number of arrays */
...) /* alternating triplets of arrays, elements and titles */
{
/* do box Plots
* This function expects `n' arrays of floats. For
* each array, a box plot is drawn. The boxed region represents
* the middle 50% of the data, while the whiskers, at either end
* of the boxed region, stretch out to cover 100% of the data. The
* middle of the boxed region is the location of the data's
* median. The 5% and 95% positions are also given and are
* displayed with a dash along the whiskers.
*
* Example (drawn horizontally):
*
* 5% +--------------------+ 95%
* ----|------| |----|------
* |--------------------|
* 25% 75%
*
* Usage1: boxPlot(p1,1, a1, n1,"title");
* where
* a1 is a pointer to an array of floats
* with n1 elements.
*
* Usage2: boxPlot(p1,2, a1,n1, "title 1",a2, n2,"t2");
*
* */
va_list ap;
char buff[512] = {0}, *cp;
FILE *fp;
float *aX, *sp, min, max, gap = 0.25, g2 = gap/4.0;
int i1, i2, i3, j,nX,ln;
va_start (ap, n);
fp = fopen(p->fname,"w");
min = FLT_MAX;
max = FLT_MIN;
for(j=1; j <= n; j++) {
aX = va_arg(ap, float *);
nX = va_arg(ap, int );
cp = va_arg(ap, char *);
if(cp != NULL) {
ln = strlen(buff);
if(j > 1)
buff[ln++] = ',';
buff[ln] = ' ';
sprintf(&buff[ln+1],"\"%s\" %d",cp,j);
}
sp = malloc(sizeof(float) * nX);
memcpy(sp,aX,nX*sizeof(float));
/* sort data */
qsort(sp,nX,sizeof(float),compareFloats);
i1 = (nX/4.0+0.5);
i2 = (nX/2.0+0.5);
i3 = (3 * nX/4.0 + 0.5);
if(sp[0] < min)
min = sp[0]; /*sp[i1];*/
if(sp[nX-1] > max)
max = sp[nX-1]; /*sp[i3];*/
fprintf(fp,"%d %g %g %g %g %g \n",
j, sp[i2], /* x,y */
j-gap,j+gap, /* xlow, xhigh */
sp[i1], sp[i3]); /*ylow, yhigh */
Send_2_plot_(p,"set arrow from %d,%g to %d,%g nohead\n",
j,sp[0], j, sp[i1]);
Send_2_plot_(p,"set arrow from %g,%g to %g,%g nohead\n",
j-g2,sp[(int)(nX*0.05)], j+g2, sp[(int)(nX*0.05)]);
Send_2_plot_(p,"set arrow from %d,%g to %d,%g nohead\n",
j,sp[nX-1], j, sp[i3]);
Send_2_plot_(p,"set arrow from %g,%g to %g,%g nohead\n",
j-g2,sp[(int)(nX*0.95)], j+g2, sp[(int)(nX*0.95)]);
free(sp);
}
fclose(fp);
if(max > 0)
gap = max/20.0;
else
gap = -max/20.0;
if(buff[0] != '\0') {
printf("buff = [%s]\n",buff);
Send_2_plot_(p,"set xtics (%s)",buff);
}
Send_2_plot_(p,"plot [0:%d] [%g:%g] '%s' with "
"boxxy; set noarrow; set xtics",j,min-gap,max+gap,p->fname);
va_end (ap);
}
void * closePlot(plot_t *p)
{
if(p != NULL) {
pclose(p->fp);
remove(p->fname);
free(p);
}
return NULL;
}
plot_t * openPlot(char * plotname)
{
plot_t * plot = (plot_t*)calloc(sizeof(plot_t),1);
if(plot != NULL) {
plot->fp = popen("gnuplot","w");
setvbuf(plot->fp,NULL,_IOLBF,0);
setFontSize(plot,12); /* 12 point */
if(plotname != NULL) {
Send_2_plot_(plot,"set title '%s'; set nokey",plotname);
}
tmpnam(plot->fname);
setLineType(plot,"lines");
}
return plot;
}
plot_t * openmPlot(char * plotname,
int nrow,
int ncol)
{
plot_t * plot = openPlot(plotname);
if(plot != NULL) {
plot->ncol = ncol;
plot->nrow = nrow;
send2plot(plot,"set multiplot");
}
return plot;
}
void ready4Output(plot_t *p1, char *filename, char *mode)
{
Send_2_plot_(p1,"set term post %s %d",mode, getFontSize(p1));
Send_2_plot_(p1,"set output \'%s\'",filename);
}
void savePlot(plot_t *p1, char *fname, char * mode)
{
/* save plot as a postscript file of name `fname'
* mode = landscape, portrait, eps or default
*/
Send_2_plot_(p1,"set term post %s %d",mode, getFontSize(p1));
Send_2_plot_(p1,"set output \'%s\'",fname);
send2plot(p1,"replot");
send2plot(p1,"set term x11");
send2plot(p1,"replot");
}
void printPlot(plot_t *p1)
{
savePlot(p1,"printfile.ps","landscape");
system("lpr printfile.ps");
remove("printfile.ps");
}
void selectPlot(plot_t *p1, /* plot */
int N) /* plot number */
{
float xp, yp, xinc, yinc;
char buf[512];
xinc = 1.0/getPlotncol(p1);
yinc = 1.0/getPlotnrow(p1);
N--;
yp = 1 - N/getPlotncol(p1) * yinc - yinc;
xp = N%getPlotncol(p1);
xp *= xinc;
sprintf(buf,"set size %g, %g; set origin %g, %g",
xinc, yinc,xp,yp);
send2plot(p1,buf);
}
void clearmPlot(plot_t *p1, /* plot */
int N) /* plot number */
{
selectPlot(p1,N);
send2plot(p1,"clear");
}
void dataMPlot(plot_t *p,
char * (*f)(), /* return the name of the file where */
/* data is stored */
int nv, /* number of vectors in vecs */
void **vecs, /* array of vectors */
int *lens) /* array of lengths to vecs */
{
/*
Plot multiply data arrays to one display.
Assumes that plot title, line style etc have been
handled elsewhere.
*/
char *buff;
char buf[256];
int blen = 256;
char **names = malloc(nv * sizeof(char*));
char *tmp;
int i,k, tl = 0;
for(i=0;i