PLplot 5.9.6
|
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 }