Back to index

plt-scheme  4.2.1
plhist.c
Go to the documentation of this file.
00001 /* $Id: plhist.c,v 1.1 2004/03/01 20:54:52 cozmic Exp $
00002 
00003        Histogram plotter.
00004 */
00005 
00006 #include "plplotP.h"
00007 
00008 /*----------------------------------------------------------------------*\
00009  * void plhist()
00010  *
00011  * Draws a histogram of n values of a variable in array data[0..n-1] in
00012  * the range datmin to datmax using nbin bins. If "flags"'s first bit is 1, the
00013  * histogram is plotted in the current window. If not, the routine calls
00014  * "plenv" to set up the graphics environment.
00015  * 
00016  * If flags's second bit is set, then items which fall outside the bin
00017  * range are ignored.
00018  * 
00019  * If flags's third bit is set, the outside bars are the same size
00020  * as the rest.  The default old behaviour was for the first and last
00021  * bars to expand visually to fill the entire available space.
00022 \*----------------------------------------------------------------------*/
00023 
00024 void
00025 c_plhist(PLINT n, PLFLT *data, PLFLT datmin, PLFLT datmax,
00026         PLINT nbin, PLINT flags)
00027 {
00028     PLINT i, bin;
00029     PLFLT *x, *y, dx, ymax;
00030 
00031     if (plsc->level < 1) {
00032        plabort("plhist: Please call plinit first");
00033        return;
00034     }
00035     if (plsc->level < 3 && (flags & 1)) {
00036        plabort("plhist: Please set up window first");
00037        return;
00038     }
00039     if (datmin >= datmax) {
00040        plabort("plhist: Data range invalid");
00041        return;
00042     }
00043     if ( ! (x = (PLFLT *) malloc((size_t) nbin * sizeof(PLFLT)))) {
00044        plabort("plhist: Out of memory");
00045        return;
00046     }
00047     if ( ! (y = (PLFLT *) malloc((size_t) nbin * sizeof(PLFLT)))) {
00048        free((void *) x);
00049        plabort("plhist: Out of memory");
00050        return;
00051     }
00052 
00053     dx = (datmax - datmin) / nbin;
00054     for (i = 0; i < nbin; i++) {
00055        x[i] = datmin + i * dx;
00056        y[i] = 0.0;
00057     }
00058 
00059     for (i = 0; i < n; i++) {
00060        bin = (data[i] - datmin) / dx;
00061        if ((flags & 2) == 0) {
00062            bin = bin > 0 ? bin : 0;
00063            bin = bin < nbin ? bin : nbin - 1;
00064            y[bin]++;
00065        } else {
00066            if(bin >= 0 && bin < nbin) {
00067               y[bin]++;
00068            }
00069        }
00070     }
00071 
00072     if (!(flags & 1)) {
00073        ymax = 0.0;
00074        for (i = 0; i < nbin; i++)
00075            ymax = MAX(ymax, y[i]);
00076 
00077        plenv(datmin, datmax, (PLFLT) 0.0, (PLFLT) (1.1 * ymax), 0, 0);
00078     }
00079     /* We pass on the highest couple of bits to the 'plbin' routine */
00080     plbin(nbin, x, y, (flags & (4+8+16+32)) >> 2);
00081     free((void *) x);
00082     free((void *) y);
00083 }
00084 
00085 /*----------------------------------------------------------------------*\
00086  * void plbin()
00087  *
00088  * Plot a histogram using the arrays x and y to represent data values
00089  * and frequencies respectively. If flags first bit is false, x values 
00090  * denote the lower edge of the bin, and if it is true, they denote 
00091  * the center of the bin.  If flags second bit is true, then we assume 
00092  * the edge bins are the same size as the rest (i.e. the edge bins 
00093  * needn't go as far as the variables vpwxmi, vpwxma below).
00094 \*----------------------------------------------------------------------*/
00095 
00096 void
00097 c_plbin(PLINT nbin, PLFLT *x, PLFLT *y, PLINT flags)
00098 {
00099     PLINT i;
00100     PLFLT xmin, xmax, vpwxmi, vpwxma, vpwymi, vpwyma;
00101 
00102     if (plsc->level < 3) {
00103        plabort("plbin: Please set up window first");
00104        return;
00105     }
00106 
00107     /* Check x[i] are in ascending order */
00108 
00109     for (i = 0; i < nbin - 1; i++) {
00110        if (x[i] >= x[i + 1]) {
00111            plabort("plbin: Elements of x array must be increasing");
00112            return;
00113        }
00114     }
00115 
00116     plgvpw(&vpwxmi, &vpwxma, &vpwymi, &vpwyma);
00117     if (!(flags & 1)) {
00118        for (i = 0; i < nbin - 1; i++) {
00119            if (!(flags & 4) || (y[i] != vpwymi)) {
00120               pljoin(x[i], vpwymi, x[i], y[i]);
00121               pljoin(x[i], y[i], x[i + 1], y[i]);
00122               pljoin(x[i + 1], y[i], x[i + 1], vpwymi);
00123            }
00124        }
00125        if (flags & 2) {
00126            if (!(flags & 4) || (y[i] != vpwymi)) {
00127               int xm = x[i] + (x[i] - x[i-1]);
00128               pljoin(x[i], vpwymi, x[i], y[i]);
00129               pljoin(x[i], y[i], xm, y[i]);
00130               pljoin(xm, y[i], xm, vpwymi);
00131            }
00132        } else {
00133            if (x[i] < vpwxma) {
00134               if (!(flags & 4) || (y[i] != vpwymi)) {
00135                   pljoin(x[i], vpwymi, x[i], y[i]);
00136                   pljoin(x[i], y[i], vpwxma, y[i]);
00137                   pljoin(vpwxma, y[i], vpwxma, vpwymi);
00138               }
00139            }
00140        }
00141     } else {
00142        if (nbin < 2)
00143            return;
00144        if (flags & 2) {
00145            xmin = MAX(vpwxmi, 0.5 * (3 * x[0] - x[1]));
00146        } else {
00147            xmin = vpwxmi;
00148        }
00149        /* Vince fixed bug May 1998 */
00150        xmax = MAX(0.5 * (x[0] + x[1]), vpwxmi);
00151        if (xmin < xmax) {
00152            pljoin(xmin, vpwymi, xmin, y[0]);
00153            pljoin(xmin, y[0], xmax, y[0]);
00154            pljoin(xmax, y[0], xmax, vpwymi);
00155        }
00156        for (i = 1; i < nbin - 1; i++) {
00157            xmin = xmax;
00158            xmax = MIN(0.5 * (x[i] + x[i + 1]), vpwxma);
00159            if (!(flags & 4) || (y[i] != vpwymi)) {
00160               pljoin(xmin, vpwymi, xmin, y[i]);
00161               pljoin(xmin, y[i], xmax, y[i]);
00162               pljoin(xmax, y[i], xmax, vpwymi);
00163            }
00164        }
00165        xmin = xmax;
00166        xmax = vpwxma;
00167        if (flags & 2) {
00168            xmax = MIN(vpwxma, 0.5 * (3 * x[i] - x[i-1]));
00169        } else {
00170            xmax = vpwxma;
00171        }
00172        if (xmin < xmax) {
00173            if (!(flags & 4) || (y[i] != vpwymi)) {
00174               pljoin(xmin, vpwymi, xmin, y[i]);
00175               pljoin(xmin, y[i], xmax, y[i]);
00176               pljoin(xmax, y[i], xmax, vpwymi);
00177            }
00178        }
00179     }
00180 }