xref: /petsc/src/sys/classes/draw/utils/hists.c (revision f37c82fbca2ef2d9869799d3305350a5f272bd86)
1 
2 /*
3   Contains the data structure for plotting a histogram in a window with an axis.
4 */
5 #include <petscdraw.h>         /*I "petscdraw.h" I*/
6 #include <petsc-private/petscimpl.h>         /*I "petscsys.h" I*/
7 #include <petscviewer.h>         /*I "petscviewer.h" I*/
8 
9 PetscClassId PETSC_DRAWHG_CLASSID = 0;
10 
11 struct _p_PetscDrawHG {
12   PETSCHEADER(int);
13   PetscErrorCode (*destroy)(PetscDrawSP);
14   PetscErrorCode (*view)(PetscDrawSP,PetscViewer);
15   PetscDraw      win;
16   PetscDrawAxis  axis;
17   PetscReal      xmin,xmax;
18   PetscReal      ymin,ymax;
19   int            numBins;
20   int            maxBins;
21   PetscReal      *bins;
22   int            numValues;
23   int            maxValues;
24   PetscReal      *values;
25   int            color;
26   PetscBool      calcStats;
27   PetscBool      integerBins;
28 };
29 
30 #define CHUNKSIZE 100
31 
32 #undef __FUNCT__
33 #define __FUNCT__ "PetscDrawHGCreate"
34 /*@C
35    PetscDrawHGCreate - Creates a histogram data structure.
36 
37    Collective over PetscDraw
38 
39    Input Parameters:
40 +  draw  - The window where the graph will be made
41 -  bins - The number of bins to use
42 
43    Output Parameters:
44 .  hist - The histogram context
45 
46    Level: intermediate
47 
48    Concepts: histogram^creating
49 
50 .seealso: PetscDrawHGDestroy()
51 
52 @*/
53 PetscErrorCode  PetscDrawHGCreate(PetscDraw draw, int bins, PetscDrawHG *hist)
54 {
55   PetscDrawHG    h;
56   MPI_Comm       comm;
57   PetscBool      isnull;
58   PetscErrorCode ierr;
59 
60   PetscFunctionBegin;
61   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID,1);
62   PetscValidPointer(hist,3);
63   ierr = PetscObjectGetComm((PetscObject) draw, &comm);CHKERRQ(ierr);
64   ierr = PetscHeaderCreate(h, _p_PetscDrawHG, int, PETSC_DRAWHG_CLASSID,  "PetscDrawHG", "Histogram", "Draw", comm, PetscDrawHGDestroy, NULL);CHKERRQ(ierr);
65 
66   h->view        = NULL;
67   h->destroy     = NULL;
68   h->win         = draw;
69 
70   ierr = PetscObjectReference((PetscObject) draw);CHKERRQ(ierr);
71 
72   h->color       = PETSC_DRAW_GREEN;
73   h->xmin        = PETSC_MAX_REAL;
74   h->xmax        = PETSC_MIN_REAL;
75   h->ymin        = 0.;
76   h->ymax        = 1.;
77   h->numBins     = bins;
78   h->maxBins     = bins;
79 
80   ierr = PetscMalloc(h->maxBins * sizeof(PetscReal), &h->bins);CHKERRQ(ierr);
81 
82   h->numValues   = 0;
83   h->maxValues   = CHUNKSIZE;
84   h->calcStats   = PETSC_FALSE;
85   h->integerBins = PETSC_FALSE;
86 
87   ierr = PetscMalloc(h->maxValues * sizeof(PetscReal), &h->values);CHKERRQ(ierr);
88   ierr = PetscLogObjectMemory(h, (h->maxBins + h->maxValues)*sizeof(PetscReal));CHKERRQ(ierr);
89   ierr = PetscObjectTypeCompare((PetscObject) draw, PETSC_DRAW_NULL, &isnull);CHKERRQ(ierr);
90 
91   if (!isnull) {
92     ierr = PetscDrawAxisCreate(draw, &h->axis);CHKERRQ(ierr);
93     ierr = PetscLogObjectParent(h, h->axis);CHKERRQ(ierr);
94   } else h->axis = NULL;
95   *hist = h;
96   PetscFunctionReturn(0);
97 }
98 
99 #undef __FUNCT__
100 #define __FUNCT__ "PetscDrawHGSetNumberBins"
101 /*@
102    PetscDrawHGSetNumberBins - Change the number of bins that are to be drawn.
103 
104    Not Collective (ignored except on processor 0 of PetscDrawHG)
105 
106    Input Parameter:
107 +  hist - The histogram context.
108 -  dim  - The number of curves.
109 
110    Level: intermediate
111 
112    Concepts: histogram^setting number of bins
113 
114 @*/
115 PetscErrorCode  PetscDrawHGSetNumberBins(PetscDrawHG hist, int bins)
116 {
117   PetscErrorCode ierr;
118 
119   PetscFunctionBegin;
120   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
121   if (hist->maxBins < bins) {
122     ierr = PetscFree(hist->bins);CHKERRQ(ierr);
123     ierr = PetscMalloc(bins * sizeof(PetscReal), &hist->bins);CHKERRQ(ierr);
124     ierr = PetscLogObjectMemory(hist, (bins - hist->maxBins) * sizeof(PetscReal));CHKERRQ(ierr);
125 
126     hist->maxBins = bins;
127   }
128   hist->numBins = bins;
129   PetscFunctionReturn(0);
130 }
131 
132 #undef __FUNCT__
133 #define __FUNCT__ "PetscDrawHGReset"
134 /*@
135   PetscDrawHGReset - Clears histogram to allow for reuse with new data.
136 
137   Not Collective (ignored except on processor 0 of PetscDrawHG)
138 
139   Input Parameter:
140 . hist - The histogram context.
141 
142   Level: intermediate
143 
144   Concepts: histogram^resetting
145 @*/
146 PetscErrorCode  PetscDrawHGReset(PetscDrawHG hist)
147 {
148   PetscFunctionBegin;
149   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
150   hist->xmin      = PETSC_MAX_REAL;
151   hist->xmax      = PETSC_MIN_REAL;
152   hist->ymin      = 0.0;
153   hist->ymax      = 0.0;
154   hist->numValues = 0;
155   PetscFunctionReturn(0);
156 }
157 
158 #undef __FUNCT__
159 #define __FUNCT__ "PetscDrawHGDestroy"
160 /*@C
161   PetscDrawHGDestroy - Frees all space taken up by histogram data structure.
162 
163   Collective over PetscDrawHG
164 
165   Input Parameter:
166 . hist - The histogram context
167 
168   Level: intermediate
169 
170 .seealso:  PetscDrawHGCreate()
171 @*/
172 PetscErrorCode  PetscDrawHGDestroy(PetscDrawHG *hist)
173 {
174   PetscErrorCode ierr;
175 
176   PetscFunctionBegin;
177   if (!*hist) PetscFunctionReturn(0);
178   PetscValidHeader(*hist,1);
179 
180   if (--((PetscObject)(*hist))->refct > 0) PetscFunctionReturn(0);
181   ierr = PetscDrawAxisDestroy(&(*hist)->axis);CHKERRQ(ierr);
182   ierr = PetscDrawDestroy(&(*hist)->win);CHKERRQ(ierr);
183   ierr = PetscFree((*hist)->bins);CHKERRQ(ierr);
184   ierr = PetscFree((*hist)->values);CHKERRQ(ierr);
185   ierr = PetscHeaderDestroy(hist);CHKERRQ(ierr);
186   PetscFunctionReturn(0);
187 }
188 
189 #undef __FUNCT__
190 #define __FUNCT__ "PetscDrawHGAddValue"
191 /*@
192   PetscDrawHGAddValue - Adds another value to the histogram.
193 
194   Not Collective (ignored except on processor 0 of PetscDrawHG)
195 
196   Input Parameters:
197 + hist  - The histogram
198 - value - The value
199 
200   Level: intermediate
201 
202   Concepts: histogram^adding values
203 
204 .seealso: PetscDrawHGAddValues()
205 @*/
206 PetscErrorCode  PetscDrawHGAddValue(PetscDrawHG hist, PetscReal value)
207 {
208   PetscFunctionBegin;
209   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
210   /* Allocate more memory if necessary */
211   if (hist->numValues >= hist->maxValues) {
212     PetscReal      *tmp;
213     PetscErrorCode ierr;
214 
215     ierr = PetscMalloc((hist->maxValues+CHUNKSIZE) * sizeof(PetscReal), &tmp);CHKERRQ(ierr);
216     ierr = PetscLogObjectMemory(hist, CHUNKSIZE * sizeof(PetscReal));CHKERRQ(ierr);
217     ierr = PetscMemcpy(tmp, hist->values, hist->maxValues * sizeof(PetscReal));CHKERRQ(ierr);
218     ierr = PetscFree(hist->values);CHKERRQ(ierr);
219 
220     hist->values     = tmp;
221     hist->maxValues += CHUNKSIZE;
222   }
223   /* I disagree with the original Petsc implementation here. There should be no overshoot, but rather the
224      stated convention of using half-open intervals (always the way to go) */
225   if (!hist->numValues) {
226     hist->xmin = value;
227     hist->xmax = value;
228 #if 1
229   } else {
230     /* Update limits */
231     if (value > hist->xmax) hist->xmax = value;
232     if (value < hist->xmin) hist->xmin = value;
233 #else
234   } else if (hist->numValues == 1) {
235     /* Update limits -- We need to overshoot the largest value somewhat */
236     if (value > hist->xmax) hist->xmax = value + 0.001*(value - hist->xmin)/hist->numBins;
237     if (value < hist->xmin) {
238       hist->xmin = value;
239       hist->xmax = hist->xmax + 0.001*(hist->xmax - hist->xmin)/hist->numBins;
240     }
241   } else {
242     /* Update limits -- We need to overshoot the largest value somewhat */
243     if (value > hist->xmax) hist->xmax = value + 0.001*(hist->xmax - hist->xmin)/hist->numBins;
244     if (value < hist->xmin) hist->xmin = value;
245 #endif
246   }
247 
248   hist->values[hist->numValues++] = value;
249   PetscFunctionReturn(0);
250 }
251 
252 #undef __FUNCT__
253 #define __FUNCT__ "PetscDrawHGDraw"
254 /*@
255   PetscDrawHGDraw - Redraws a histogram.
256 
257   Not Collective (ignored except on processor 0 of PetscDrawHG)
258 
259   Input Parameter:
260 . hist - The histogram context
261 
262   Level: intermediate
263 
264 @*/
265 PetscErrorCode  PetscDrawHGDraw(PetscDrawHG hist)
266 {
267   PetscDraw      draw = hist->win;
268   PetscBool      isnull;
269   PetscReal      xmin,xmax,ymin,ymax,*bins,*values,binSize,binLeft,binRight,maxHeight,mean,var;
270   char           title[256];
271   char           xlabel[256];
272   PetscInt       numBins,numBinsOld,numValues,initSize,i,p,bcolor,color;
273   PetscErrorCode ierr;
274 
275   PetscFunctionBegin;
276   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
277   ierr = PetscObjectTypeCompare((PetscObject) draw, PETSC_DRAW_NULL, &isnull);CHKERRQ(ierr);
278   if (isnull) PetscFunctionReturn(0);
279   if ((hist->xmin >= hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(0);
280   if (hist->numValues < 1) PetscFunctionReturn(0);
281 
282 #if 0
283   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)hist),&rank);CHKERRQ(ierr);
284   if (rank) PetscFunctionReturn(0);
285 #endif
286 
287   color = hist->color;
288   if (color == PETSC_DRAW_ROTATE) bcolor = 2;
289   else bcolor = color;
290 
291   xmin      = hist->xmin;
292   xmax      = hist->xmax;
293   ymin      = hist->ymin;
294   ymax      = hist->ymax;
295   numValues = hist->numValues;
296   values    = hist->values;
297   mean      = 0.0;
298   var       = 0.0;
299 
300   ierr = PetscDrawClear(draw);CHKERRQ(ierr);
301   if (xmin == xmax) {
302     /* Calculate number of points in each bin */
303     bins    = hist->bins;
304     bins[0] = 0.;
305     for (p = 0; p < numValues; p++) {
306       if (values[p] == xmin) bins[0]++;
307       mean += values[p];
308       var  += values[p]*values[p];
309     }
310     maxHeight = bins[0];
311     if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
312     xmax = xmin + 1;
313     ierr = PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax);CHKERRQ(ierr);
314     if (hist->calcStats) {
315       mean /= numValues;
316       if (numValues > 1) var = (var - numValues*mean*mean) / (numValues-1);
317       else var = 0.0;
318       ierr = PetscSNPrintf(title, 256, "Mean: %g  Var: %g", (double)mean, (double)var);CHKERRQ(ierr);
319       ierr = PetscSNPrintf(xlabel,256, "Total: %D", numValues);CHKERRQ(ierr);
320       ierr = PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL);CHKERRQ(ierr);
321     }
322     ierr = PetscDrawAxisDraw(hist->axis);CHKERRQ(ierr);
323     /* Draw bins */
324     binLeft  = xmin;
325     binRight = xmax;
326     ierr = PetscDrawRectangle(draw,binLeft,ymin,binRight,bins[0],bcolor,bcolor,bcolor,bcolor);CHKERRQ(ierr);
327 
328     if (color == PETSC_DRAW_ROTATE && bins[0] != 0.0) bcolor++;
329     if (bcolor > 31) bcolor = 2;
330 
331     ierr = PetscDrawLine(draw,binLeft,ymin,binLeft,bins[0],PETSC_DRAW_BLACK);CHKERRQ(ierr);
332     ierr = PetscDrawLine(draw,binRight,ymin,binRight,bins[0],PETSC_DRAW_BLACK);CHKERRQ(ierr);
333     ierr = PetscDrawLine(draw,binLeft,bins[0],binRight,bins[0],PETSC_DRAW_BLACK);CHKERRQ(ierr);
334   } else {
335     numBins    = hist->numBins;
336     numBinsOld = hist->numBins;
337     if (hist->integerBins && (((int) xmax - xmin) + 1.0e-05 > xmax - xmin)) {
338       initSize = (int) ((int) xmax - xmin)/numBins;
339       while (initSize*numBins != (int) xmax - xmin) {
340         initSize = PetscMax(initSize - 1, 1);
341         numBins  = (int) ((int) xmax - xmin)/initSize;
342         ierr     = PetscDrawHGSetNumberBins(hist, numBins);CHKERRQ(ierr);
343       }
344     }
345     binSize = (xmax - xmin)/numBins;
346     bins    = hist->bins;
347 
348     ierr = PetscMemzero(bins, numBins * sizeof(PetscReal));CHKERRQ(ierr);
349 
350     maxHeight = 0.0;
351     for (i = 0; i < numBins; i++) {
352       binLeft  = xmin + binSize*i;
353       binRight = xmin + binSize*(i+1);
354       for (p = 0; p < numValues; p++) {
355         if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
356         /* Handle last bin separately */
357         if ((i == numBins-1) && (values[p] == binRight)) bins[i]++;
358         if (!i) {
359           mean += values[p];
360           var  += values[p]*values[p];
361         }
362       }
363       maxHeight = PetscMax(maxHeight, bins[i]);
364     }
365     if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
366 
367     ierr = PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax);CHKERRQ(ierr);
368     if (hist->calcStats) {
369       mean /= numValues;
370       if (numValues > 1) var = (var - numValues*mean*mean) / (numValues-1);
371       else var = 0.0;
372 
373       ierr = PetscSNPrintf(title, 256,"Mean: %g  Var: %g", (double)mean, (double)var);CHKERRQ(ierr);
374       ierr = PetscSNPrintf(xlabel,256, "Total: %D", numValues);CHKERRQ(ierr);
375       ierr = PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL);CHKERRQ(ierr);
376     }
377     ierr = PetscDrawAxisDraw(hist->axis);CHKERRQ(ierr);
378     /* Draw bins */
379     for (i = 0; i < numBins; i++) {
380       binLeft  = xmin + binSize*i;
381       binRight = xmin + binSize*(i+1);
382       ierr = PetscDrawRectangle(draw,binLeft,ymin,binRight,bins[i],bcolor,bcolor,bcolor,bcolor);CHKERRQ(ierr);
383       if (color == PETSC_DRAW_ROTATE && bins[i]) bcolor++;
384       if (bcolor > 31) bcolor = 2;
385       ierr = PetscDrawLine(draw,binLeft,ymin,binLeft,bins[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
386       ierr = PetscDrawLine(draw,binRight,ymin,binRight,bins[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
387       ierr = PetscDrawLine(draw,binLeft,bins[i],binRight,bins[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
388     }
389     ierr = PetscDrawHGSetNumberBins(hist, numBinsOld);CHKERRQ(ierr);
390   }
391   ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr);
392   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
393   PetscFunctionReturn(0);
394 }
395 
396 #undef __FUNCT__
397 #define __FUNCT__ "PetscDrawHGView"
398 /*@
399   PetscDrawHGView - Prints the histogram information.
400 
401   Not collective
402 
403   Input Parameter:
404 . hist - The histogram context
405 
406   Level: beginner
407 
408 .keywords:  draw, histogram
409 @*/
410 PetscErrorCode  PetscDrawHGView(PetscDrawHG hist,PetscViewer viewer)
411 {
412   PetscReal      xmax,xmin,*bins,*values,binSize,binLeft,binRight,mean,var;
413   PetscErrorCode ierr;
414   PetscInt       numBins,numBinsOld,numValues,initSize,i,p;
415 
416   PetscFunctionBegin;
417   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
418   if ((hist->xmin > hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(0);
419   if (hist->numValues < 1) PetscFunctionReturn(0);
420 
421   if (!viewer){
422     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)hist),&viewer);CHKERRQ(ierr);
423   }
424   xmax      = hist->xmax;
425   xmin      = hist->xmin;
426   numValues = hist->numValues;
427   values    = hist->values;
428   mean      = 0.0;
429   var       = 0.0;
430   if (xmax == xmin) {
431     /* Calculate number of points in the bin */
432     bins    = hist->bins;
433     bins[0] = 0.;
434     for (p = 0; p < numValues; p++) {
435       if (values[p] == xmin) bins[0]++;
436       mean += values[p];
437       var  += values[p]*values[p];
438     }
439     /* Draw bins */
440     ierr = PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", 0, (double)xmin, (double)xmax, (double)bins[0]);CHKERRQ(ierr);
441   } else {
442     numBins    = hist->numBins;
443     numBinsOld = hist->numBins;
444     if (hist->integerBins && (((int) xmax - xmin) + 1.0e-05 > xmax - xmin)) {
445       initSize = (int) ((int) xmax - xmin)/numBins;
446       while (initSize*numBins != (int) xmax - xmin) {
447         initSize = PetscMax(initSize - 1, 1);
448         numBins  = (int) ((int) xmax - xmin)/initSize;
449         ierr     = PetscDrawHGSetNumberBins(hist, numBins);CHKERRQ(ierr);
450       }
451     }
452     binSize = (xmax - xmin)/numBins;
453     bins    = hist->bins;
454 
455     /* Calculate number of points in each bin */
456     ierr = PetscMemzero(bins, numBins * sizeof(PetscReal));CHKERRQ(ierr);
457     for (i = 0; i < numBins; i++) {
458       binLeft  = xmin + binSize*i;
459       binRight = xmin + binSize*(i+1);
460       for (p = 0; p < numValues; p++) {
461         if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
462         /* Handle last bin separately */
463         if ((i == numBins-1) && (values[p] == binRight)) bins[i]++;
464         if (!i) {
465           mean += values[p];
466           var  += values[p]*values[p];
467         }
468       }
469     }
470     /* Draw bins */
471     for (i = 0; i < numBins; i++) {
472       binLeft  = xmin + binSize*i;
473       binRight = xmin + binSize*(i+1);
474       ierr = PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", (int)i, (double)binLeft, (double)binRight, (double)bins[i]);CHKERRQ(ierr);
475     }
476     ierr = PetscDrawHGSetNumberBins(hist, numBinsOld);CHKERRQ(ierr);
477   }
478 
479   if (hist->calcStats) {
480     mean /= numValues;
481     if (numValues > 1) var = (var - numValues*mean*mean) / (numValues-1);
482     else var = 0.0;
483     ierr = PetscViewerASCIIPrintf(viewer, "Mean: %G  Var: %G\n", (double)mean, (double)var);CHKERRQ(ierr);
484     ierr = PetscViewerASCIIPrintf(viewer, "Total: %D\n", numValues);CHKERRQ(ierr);
485   }
486   PetscFunctionReturn(0);
487 }
488 
489 #undef __FUNCT__
490 #define __FUNCT__ "PetscDrawHGSetColor"
491 /*@
492   PetscDrawHGSetColor - Sets the color the bars will be drawn with.
493 
494   Not Collective (ignored except on processor 0 of PetscDrawHG)
495 
496   Input Parameters:
497 + hist - The histogram context
498 - color - one of the colors defined in petscdraw.h or PETSC_DRAW_ROTATE to make each bar a
499           different color
500 
501   Level: intermediate
502 
503 @*/
504 PetscErrorCode  PetscDrawHGSetColor(PetscDrawHG hist, int color)
505 {
506   PetscFunctionBegin;
507   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
508   hist->color = color;
509   PetscFunctionReturn(0);
510 }
511 
512 #undef __FUNCT__
513 #define __FUNCT__ "PetscDrawHGSetLimits"
514 /*@
515   PetscDrawHGSetLimits - Sets the axis limits for a histogram. If more
516   points are added after this call, the limits will be adjusted to
517   include those additional points.
518 
519   Not Collective (ignored except on processor 0 of PetscDrawHG)
520 
521   Input Parameters:
522 + hist - The histogram context
523 - x_min,x_max,y_min,y_max - The limits
524 
525   Level: intermediate
526 
527   Concepts: histogram^setting axis
528 @*/
529 PetscErrorCode  PetscDrawHGSetLimits(PetscDrawHG hist, PetscReal x_min, PetscReal x_max, int y_min, int y_max)
530 {
531   PetscFunctionBegin;
532   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
533   hist->xmin = x_min;
534   hist->xmax = x_max;
535   hist->ymin = y_min;
536   hist->ymax = y_max;
537   PetscFunctionReturn(0);
538 }
539 
540 #undef __FUNCT__
541 #define __FUNCT__ "PetscDrawHGCalcStats"
542 /*@
543   PetscDrawHGCalcStats - Turns on calculation of descriptive statistics
544 
545   Not collective
546 
547   Input Parameters:
548 + hist - The histogram context
549 - calc - Flag for calculation
550 
551   Level: intermediate
552 
553 .keywords:  draw, histogram, statistics
554 
555 @*/
556 PetscErrorCode  PetscDrawHGCalcStats(PetscDrawHG hist, PetscBool calc)
557 {
558   PetscFunctionBegin;
559   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
560   hist->calcStats = calc;
561   PetscFunctionReturn(0);
562 }
563 
564 #undef __FUNCT__
565 #define __FUNCT__ "PetscDrawHGIntegerBins"
566 /*@
567   PetscDrawHGIntegerBins - Turns on integer width bins
568 
569   Not collective
570 
571   Input Parameters:
572 + hist - The histogram context
573 - ints - Flag for integer width bins
574 
575   Level: intermediate
576 
577 .keywords:  draw, histogram, statistics
578 @*/
579 PetscErrorCode  PetscDrawHGIntegerBins(PetscDrawHG hist, PetscBool ints)
580 {
581   PetscFunctionBegin;
582   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
583   hist->integerBins = ints;
584   PetscFunctionReturn(0);
585 }
586 
587 #undef __FUNCT__
588 #define __FUNCT__ "PetscDrawHGGetAxis"
589 /*@C
590   PetscDrawHGGetAxis - Gets the axis context associated with a histogram.
591   This is useful if one wants to change some axis property, such as
592   labels, color, etc. The axis context should not be destroyed by the
593   application code.
594 
595   Not Collective (ignored except on processor 0 of PetscDrawHG)
596 
597   Input Parameter:
598 . hist - The histogram context
599 
600   Output Parameter:
601 . axis - The axis context
602 
603   Level: intermediate
604 
605 @*/
606 PetscErrorCode  PetscDrawHGGetAxis(PetscDrawHG hist, PetscDrawAxis *axis)
607 {
608   PetscFunctionBegin;
609   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
610   PetscValidPointer(axis,2);
611   *axis = hist->axis;
612   PetscFunctionReturn(0);
613 }
614 
615 #undef __FUNCT__
616 #define __FUNCT__ "PetscDrawHGGetDraw"
617 /*@C
618   PetscDrawHGGetDraw - Gets the draw context associated with a histogram.
619 
620   Not Collective, PetscDraw is parallel if PetscDrawHG is parallel
621 
622   Input Parameter:
623 . hist - The histogram context
624 
625   Output Parameter:
626 . win  - The draw context
627 
628   Level: intermediate
629 
630 @*/
631 PetscErrorCode  PetscDrawHGGetDraw(PetscDrawHG hist, PetscDraw *win)
632 {
633   PetscFunctionBegin;
634   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
635   PetscValidPointer(win,2);
636   *win = hist->win;
637   PetscFunctionReturn(0);
638 }
639 
640