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