PLplot: plhist.c Source File

PLplot 5.10.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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 }