PLplot  5.10.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
plhist.c
Go to the documentation of this file.
1 // $Id: plhist.c 11680 2011-03-27 17:57:51Z airwin $
2 //
3 // Histogram plotter.
4 //
5 // Copyright (C) 2004 Alan W. Irwin
6 //
7 // This file is part of PLplot.
8 //
9 // PLplot is free software; you can redistribute it and/or modify
10 // it under the terms of the GNU Library General Public License as published
11 // by the Free Software Foundation; either version 2 of the License, or
12 // (at your option) any later version.
13 //
14 // PLplot is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU Library General Public License for more details.
18 //
19 // You should have received a copy of the GNU Library General Public License
20 // along with PLplot; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 
24 #include "plplotP.h"
25 
26 //--------------------------------------------------------------------------
27 // void plhist()
28 //
29 // Draws a histogram of n values of a variable in array data[0..n-1] in
30 // the range datmin to datmax using nbin bins. If "flags"'s first bit is 1, the
31 // histogram is plotted in the current window. If not, the routine calls
32 // "plenv" to set up the graphics environment.
33 //
34 // If flags's second bit is set, then items which fall outside the bin
35 // range are ignored.
36 //
37 // If flags's third bit is set, the outside bars are the same size
38 // as the rest. The default old behaviour was for the first and last
39 // bars to expand visually to fill the entire available space.
40 //--------------------------------------------------------------------------
41 
42 void
43 c_plhist( PLINT n, const PLFLT *data, PLFLT datmin, PLFLT datmax,
44  PLINT nbin, PLINT flags )
45 {
46  PLINT i, bin;
47  PLFLT *x, *y, dx, ymax;
48 
49  if ( plsc->level < 1 )
50  {
51  plabort( "plhist: Please call plinit first" );
52  return;
53  }
54  if ( plsc->level < 3 && ( flags & 1 ) )
55  {
56  plabort( "plhist: Please set up window first" );
57  return;
58  }
59  if ( datmin >= datmax )
60  {
61  plabort( "plhist: Data range invalid" );
62  return;
63  }
64  if ( !( x = (PLFLT *) malloc( (size_t) nbin * sizeof ( PLFLT ) ) ) )
65  {
66  plabort( "plhist: Out of memory" );
67  return;
68  }
69  if ( !( y = (PLFLT *) malloc( (size_t) nbin * sizeof ( PLFLT ) ) ) )
70  {
71  free( (void *) x );
72  plabort( "plhist: Out of memory" );
73  return;
74  }
75 
76  dx = ( datmax - datmin ) / nbin;
77  for ( i = 0; i < nbin; i++ )
78  {
79  x[i] = datmin + i * dx;
80  y[i] = 0.0;
81  }
82 
83  for ( i = 0; i < n; i++ )
84  {
85  bin = (PLINT) ( ( data[i] - datmin ) / dx );
86  if ( ( flags & 2 ) == 0 )
87  {
88  bin = bin > 0 ? bin : 0;
89  bin = bin < nbin ? bin : nbin - 1;
90  y[bin]++;
91  }
92  else
93  {
94  if ( bin >= 0 && bin < nbin )
95  {
96  y[bin]++;
97  }
98  }
99  }
100 
101  if ( !( flags & 1 ) )
102  {
103  ymax = 0.0;
104  for ( i = 0; i < nbin; i++ )
105  ymax = MAX( ymax, y[i] );
106 
107  plenv( datmin, datmax, (PLFLT) 0.0, (PLFLT) ( 1.1 * ymax ), 0, 0 );
108  }
109  // We pass on the highest couple of bits to the 'plbin' routine
110  plbin( nbin, x, y, ( flags & ( 4 + 8 + 16 + 32 ) ) >> 2 );
111  free( (void *) x );
112  free( (void *) y );
113 }
114 
115 //--------------------------------------------------------------------------
116 // void plbin()
117 //
118 // Plot a histogram using the arrays x and y to represent data values
119 // and frequencies respectively. If flags first bit is false, x values
120 // denote the lower edge of the bin, and if it is true, they denote
121 // the center of the bin. If flags second bit is true, then we assume
122 // the edge bins are the same size as the rest (i.e. the edge bins
123 // needn't go as far as the variables vpwxmi, vpwxma below).
124 //--------------------------------------------------------------------------
125 
126 void
127 c_plbin( PLINT nbin, const PLFLT *x, const PLFLT *y, PLINT flags )
128 {
129  PLINT i;
130  PLFLT xmin, xmax, vpwxmi, vpwxma, vpwymi, vpwyma;
131 
132  if ( plsc->level < 3 )
133  {
134  plabort( "plbin: Please set up window first" );
135  return;
136  }
137 
138  // Check x[i] are in ascending order
139 
140  for ( i = 0; i < nbin - 1; i++ )
141  {
142  if ( x[i] >= x[i + 1] )
143  {
144  plabort( "plbin: Elements of x array must be increasing" );
145  return;
146  }
147  }
148 
149  plP_xgvpw( &vpwxmi, &vpwxma, &vpwymi, &vpwyma );
150  if ( !( flags & 1 ) )
151  {
152  for ( i = 0; i < nbin - 1; i++ )
153  {
154  if ( !( flags & 4 ) || ( y[i] != vpwymi ) )
155  {
156  pljoin( x[i], vpwymi, x[i], y[i] );
157  pljoin( x[i], y[i], x[i + 1], y[i] );
158  pljoin( x[i + 1], y[i], x[i + 1], vpwymi );
159  }
160  }
161  if ( flags & 2 )
162  {
163  if ( !( flags & 4 ) || ( y[i] != vpwymi ) )
164  {
165  int xm = (int) ( x[i] + ( x[i] - x[i - 1] ) );
166  pljoin( x[i], vpwymi, x[i], y[i] );
167  pljoin( x[i], y[i], xm, y[i] );
168  pljoin( xm, y[i], xm, vpwymi );
169  }
170  }
171  else
172  {
173  if ( x[i] < vpwxma )
174  {
175  if ( !( flags & 4 ) || ( y[i] != vpwymi ) )
176  {
177  pljoin( x[i], vpwymi, x[i], y[i] );
178  pljoin( x[i], y[i], vpwxma, y[i] );
179  pljoin( vpwxma, y[i], vpwxma, vpwymi );
180  }
181  }
182  }
183  }
184  else
185  {
186  if ( nbin < 2 )
187  return;
188  if ( flags & 2 )
189  {
190  xmin = MAX( vpwxmi, 0.5 * ( 3 * x[0] - x[1] ) );
191  }
192  else
193  {
194  xmin = vpwxmi;
195  }
196  // Vince fixed bug May 1998
197  xmax = MAX( 0.5 * ( x[0] + x[1] ), vpwxmi );
198  if ( xmin < xmax )
199  {
200  pljoin( xmin, vpwymi, xmin, y[0] );
201  pljoin( xmin, y[0], xmax, y[0] );
202  pljoin( xmax, y[0], xmax, vpwymi );
203  }
204  for ( i = 1; i < nbin - 1; i++ )
205  {
206  xmin = xmax;
207  xmax = MIN( 0.5 * ( x[i] + x[i + 1] ), vpwxma );
208  if ( !( flags & 4 ) || ( y[i] != vpwymi ) )
209  {
210  pljoin( xmin, vpwymi, xmin, y[i] );
211  pljoin( xmin, y[i], xmax, y[i] );
212  pljoin( xmax, y[i], xmax, vpwymi );
213  }
214  }
215  xmin = xmax;
216  xmax = vpwxma;
217  if ( flags & 2 )
218  {
219  xmax = MIN( vpwxma, 0.5 * ( 3 * x[i] - x[i - 1] ) );
220  }
221  else
222  {
223  xmax = vpwxma;
224  }
225  if ( xmin < xmax )
226  {
227  if ( !( flags & 4 ) || ( y[i] != vpwymi ) )
228  {
229  pljoin( xmin, vpwymi, xmin, y[i] );
230  pljoin( xmin, y[i], xmax, y[i] );
231  pljoin( xmax, y[i], xmax, vpwymi );
232  }
233  }
234  }
235 }