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