PLplot 5.9.6
plhist.c
00001 /* $Id$
00002  *
00003  *      Histogram plotter.
00004  *
00005  * Copyright (C) 2004  Alan W. Irwin
00006  *
00007  * This file is part of PLplot.
00008  *
00009  * PLplot is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Library Public License as published
00011  * by the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * PLplot is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU Library General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Library General Public License
00020  * along with PLplot; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00022  */
00023 
00024 #include "plplotP.h"
00025 
00026 /*----------------------------------------------------------------------*\
00027  * void plhist()
00028  *
00029  * Draws a histogram of n values of a variable in array data[0..n-1] in
00030  * the range datmin to datmax using nbin bins. If "flags"'s first bit is 1, the
00031  * histogram is plotted in the current window. If not, the routine calls
00032  * "plenv" to set up the graphics environment.
00033  *
00034  * If flags's second bit is set, then items which fall outside the bin
00035  * range are ignored.
00036  *
00037  * If flags's third bit is set, the outside bars are the same size
00038  * as the rest.  The default old behaviour was for the first and last
00039  * bars to expand visually to fill the entire available space.
00040  \*----------------------------------------------------------------------*/
00041 
00042 void
00043 c_plhist( PLINT n, PLFLT *data, PLFLT datmin, PLFLT datmax,
00044           PLINT nbin, PLINT flags )
00045 {
00046     PLINT i, bin;
00047     PLFLT *x, *y, dx, ymax;
00048 
00049     if ( plsc->level < 1 )
00050     {
00051         plabort( "plhist: Please call plinit first" );
00052         return;
00053     }
00054     if ( plsc->level < 3 && ( flags & 1 ) )
00055     {
00056         plabort( "plhist: Please set up window first" );
00057         return;
00058     }
00059     if ( datmin >= datmax )
00060     {
00061         plabort( "plhist: Data range invalid" );
00062         return;
00063     }
00064     if ( !( x = (PLFLT *) malloc( (size_t) nbin * sizeof ( PLFLT ) ) ) )
00065     {
00066         plabort( "plhist: Out of memory" );
00067         return;
00068     }
00069     if ( !( y = (PLFLT *) malloc( (size_t) nbin * sizeof ( PLFLT ) ) ) )
00070     {
00071         free( (void *) x );
00072         plabort( "plhist: Out of memory" );
00073         return;
00074     }
00075 
00076     dx = ( datmax - datmin ) / nbin;
00077     for ( i = 0; i < nbin; i++ )
00078     {
00079         x[i] = datmin + i * dx;
00080         y[i] = 0.0;
00081     }
00082 
00083     for ( i = 0; i < n; i++ )
00084     {
00085         bin = (PLINT) ( ( data[i] - datmin ) / dx );
00086         if ( ( flags & 2 ) == 0 )
00087         {
00088             bin = bin > 0 ? bin : 0;
00089             bin = bin < nbin ? bin : nbin - 1;
00090             y[bin]++;
00091         }
00092         else
00093         {
00094             if ( bin >= 0 && bin < nbin )
00095             {
00096                 y[bin]++;
00097             }
00098         }
00099     }
00100 
00101     if ( !( flags & 1 ) )
00102     {
00103         ymax = 0.0;
00104         for ( i = 0; i < nbin; i++ )
00105             ymax = MAX( ymax, y[i] );
00106 
00107         plenv( datmin, datmax, (PLFLT) 0.0, (PLFLT) ( 1.1 * ymax ), 0, 0 );
00108     }
00109     /* We pass on the highest couple of bits to the 'plbin' routine */
00110     plbin( nbin, x, y, ( flags & ( 4 + 8 + 16 + 32 ) ) >> 2 );
00111     free( (void *) x );
00112     free( (void *) y );
00113 }
00114 
00115 /*----------------------------------------------------------------------*\
00116  * void plbin()
00117  *
00118  * Plot a histogram using the arrays x and y to represent data values
00119  * and frequencies respectively. If flags first bit is false, x values
00120  * denote the lower edge of the bin, and if it is true, they denote
00121  * the center of the bin.  If flags second bit is true, then we assume
00122  * the edge bins are the same size as the rest (i.e. the edge bins
00123  * needn't go as far as the variables vpwxmi, vpwxma below).
00124  \*----------------------------------------------------------------------*/
00125 
00126 void
00127 c_plbin( PLINT nbin, PLFLT *x, PLFLT *y, PLINT flags )
00128 {
00129     PLINT i;
00130     PLFLT xmin, xmax, vpwxmi, vpwxma, vpwymi, vpwyma;
00131 
00132     if ( plsc->level < 3 )
00133     {
00134         plabort( "plbin: Please set up window first" );
00135         return;
00136     }
00137 
00138     /* Check x[i] are in ascending order */
00139 
00140     for ( i = 0; i < nbin - 1; i++ )
00141     {
00142         if ( x[i] >= x[i + 1] )
00143         {
00144             plabort( "plbin: Elements of x array must be increasing" );
00145             return;
00146         }
00147     }
00148 
00149     plP_xgvpw( &vpwxmi, &vpwxma, &vpwymi, &vpwyma );
00150     if ( !( flags & 1 ) )
00151     {
00152         for ( i = 0; i < nbin - 1; i++ )
00153         {
00154             if ( !( flags & 4 ) || ( y[i] != vpwymi ) )
00155             {
00156                 pljoin( x[i], vpwymi, x[i], y[i] );
00157                 pljoin( x[i], y[i], x[i + 1], y[i] );
00158                 pljoin( x[i + 1], y[i], x[i + 1], vpwymi );
00159             }
00160         }
00161         if ( flags & 2 )
00162         {
00163             if ( !( flags & 4 ) || ( y[i] != vpwymi ) )
00164             {
00165                 int xm = (int) ( x[i] + ( x[i] - x[i - 1] ) );
00166                 pljoin( x[i], vpwymi, x[i], y[i] );
00167                 pljoin( x[i], y[i], xm, y[i] );
00168                 pljoin( xm, y[i], xm, vpwymi );
00169             }
00170         }
00171         else
00172         {
00173             if ( x[i] < vpwxma )
00174             {
00175                 if ( !( flags & 4 ) || ( y[i] != vpwymi ) )
00176                 {
00177                     pljoin( x[i], vpwymi, x[i], y[i] );
00178                     pljoin( x[i], y[i], vpwxma, y[i] );
00179                     pljoin( vpwxma, y[i], vpwxma, vpwymi );
00180                 }
00181             }
00182         }
00183     }
00184     else
00185     {
00186         if ( nbin < 2 )
00187             return;
00188         if ( flags & 2 )
00189         {
00190             xmin = MAX( vpwxmi, 0.5 * ( 3 * x[0] - x[1] ) );
00191         }
00192         else
00193         {
00194             xmin = vpwxmi;
00195         }
00196         /* Vince fixed bug May 1998 */
00197         xmax = MAX( 0.5 * ( x[0] + x[1] ), vpwxmi );
00198         if ( xmin < xmax )
00199         {
00200             pljoin( xmin, vpwymi, xmin, y[0] );
00201             pljoin( xmin, y[0], xmax, y[0] );
00202             pljoin( xmax, y[0], xmax, vpwymi );
00203         }
00204         for ( i = 1; i < nbin - 1; i++ )
00205         {
00206             xmin = xmax;
00207             xmax = MIN( 0.5 * ( x[i] + x[i + 1] ), vpwxma );
00208             if ( !( flags & 4 ) || ( y[i] != vpwymi ) )
00209             {
00210                 pljoin( xmin, vpwymi, xmin, y[i] );
00211                 pljoin( xmin, y[i], xmax, y[i] );
00212                 pljoin( xmax, y[i], xmax, vpwymi );
00213             }
00214         }
00215         xmin = xmax;
00216         xmax = vpwxma;
00217         if ( flags & 2 )
00218         {
00219             xmax = MIN( vpwxma, 0.5 * ( 3 * x[i] - x[i - 1] ) );
00220         }
00221         else
00222         {
00223             xmax = vpwxma;
00224         }
00225         if ( xmin < xmax )
00226         {
00227             if ( !( flags & 4 ) || ( y[i] != vpwymi ) )
00228             {
00229                 pljoin( xmin, vpwymi, xmin, y[i] );
00230                 pljoin( xmin, y[i], xmax, y[i] );
00231                 pljoin( xmax, y[i], xmax, vpwymi );
00232             }
00233         }
00234     }
00235 }
 All Data Structures Files Functions