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