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