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