xref: /petsc/src/sys/classes/draw/utils/hists.c (revision 1ebf93c6b7d760d592de6ebe6cdc0debaa3caf75)
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 on 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   PetscErrorCode ierr;
57 
58   PetscFunctionBegin;
59   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID,1);
60   PetscValidLogicalCollectiveInt(draw,bins,2);
61   PetscValidPointer(hist,3);
62 
63   ierr = PetscHeaderCreate(h,PETSC_DRAWHG_CLASSID,"DrawHG","Histogram","Draw",PetscObjectComm((PetscObject)draw),PetscDrawHGDestroy,NULL);CHKERRQ(ierr);
64   ierr = PetscLogObjectParent((PetscObject)draw,(PetscObject)h);CHKERRQ(ierr);
65 
66   ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr);
67   h->win = draw;
68 
69   h->view        = NULL;
70   h->destroy     = NULL;
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 = PetscMalloc1(h->maxBins,&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 = PetscMalloc1(h->maxValues,&h->values);CHKERRQ(ierr);
87   ierr = PetscLogObjectMemory((PetscObject)h,(h->maxBins + h->maxValues)*sizeof(PetscReal));CHKERRQ(ierr);
88 
89   ierr = PetscDrawAxisCreate(draw,&h->axis);CHKERRQ(ierr);
90   ierr = PetscLogObjectParent((PetscObject)h,(PetscObject)h->axis);CHKERRQ(ierr);
91 
92   *hist = h;
93   PetscFunctionReturn(0);
94 }
95 
96 #undef __FUNCT__
97 #define __FUNCT__ "PetscDrawHGSetNumberBins"
98 /*@
99    PetscDrawHGSetNumberBins - Change the number of bins that are to be drawn.
100 
101    Logically Collective on PetscDrawHG
102 
103    Input Parameter:
104 +  hist - The histogram context.
105 -  bins  - The number of bins.
106 
107    Level: intermediate
108 
109    Concepts: histogram^setting number of bins
110 
111 @*/
112 PetscErrorCode  PetscDrawHGSetNumberBins(PetscDrawHG hist, int bins)
113 {
114   PetscErrorCode ierr;
115 
116   PetscFunctionBegin;
117   PetscValidHeaderSpecific(hist,PETSC_DRAWHG_CLASSID,1);
118   PetscValidLogicalCollectiveInt(hist,bins,2);
119 
120   if (hist->maxBins < bins) {
121     ierr = PetscFree(hist->bins);CHKERRQ(ierr);
122     ierr = PetscMalloc1(bins, &hist->bins);CHKERRQ(ierr);
123     ierr = PetscLogObjectMemory((PetscObject)hist, (bins - hist->maxBins) * sizeof(PetscReal));CHKERRQ(ierr);
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   Logically Collective on 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 
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 on 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   PetscValidHeaderSpecific(*hist,PETSC_DRAWHG_CLASSID,1);
178   if (--((PetscObject)(*hist))->refct > 0) {*hist = NULL; PetscFunctionReturn(0);}
179 
180   ierr = PetscFree((*hist)->bins);CHKERRQ(ierr);
181   ierr = PetscFree((*hist)->values);CHKERRQ(ierr);
182   ierr = PetscDrawAxisDestroy(&(*hist)->axis);CHKERRQ(ierr);
183   ierr = PetscDrawDestroy(&(*hist)->win);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   Logically Collective on 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 
210   /* Allocate more memory if necessary */
211   if (hist->numValues >= hist->maxValues) {
212     PetscReal      *tmp;
213     PetscErrorCode ierr;
214 
215     ierr = PetscMalloc1(hist->maxValues+CHUNKSIZE, &tmp);CHKERRQ(ierr);
216     ierr = PetscLogObjectMemory((PetscObject)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   Collective on 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;
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   PetscMPIInt    rank;
274   PetscErrorCode ierr;
275 
276   PetscFunctionBegin;
277   PetscValidHeaderSpecific(hist,PETSC_DRAWHG_CLASSID,1);
278   ierr = PetscDrawIsNull(hist->win,&isnull);CHKERRQ(ierr);
279   if (isnull) PetscFunctionReturn(0);
280   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)hist),&rank);CHKERRQ(ierr);
281 
282   if ((hist->xmin >= hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(0);
283   if (hist->numValues < 1) PetscFunctionReturn(0);
284 
285   color = hist->color;
286   if (color == PETSC_DRAW_ROTATE) bcolor = PETSC_DRAW_BLACK+1;
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   draw = hist->win;
299   ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr);
300   ierr = PetscDrawClear(draw);CHKERRQ(ierr);
301 
302   if (xmin == xmax) {
303     /* Calculate number of points in each bin */
304     bins    = hist->bins;
305     bins[0] = 0.;
306     for (p = 0; p < numValues; p++) {
307       if (values[p] == xmin) bins[0]++;
308       mean += values[p];
309       var  += values[p]*values[p];
310     }
311     maxHeight = bins[0];
312     if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
313     xmax = xmin + 1;
314     ierr = PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax);CHKERRQ(ierr);
315     if (hist->calcStats) {
316       mean /= numValues;
317       if (numValues > 1) var = (var - numValues*mean*mean) / (numValues-1);
318       else var = 0.0;
319       ierr = PetscSNPrintf(title, 256, "Mean: %g  Var: %g", (double)mean, (double)var);CHKERRQ(ierr);
320       ierr = PetscSNPrintf(xlabel,256, "Total: %D", numValues);CHKERRQ(ierr);
321       ierr = PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL);CHKERRQ(ierr);
322     }
323     ierr = PetscDrawAxisDraw(hist->axis);CHKERRQ(ierr);
324     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
325     if (!rank) { /* Draw bins */
326       binLeft  = xmin;
327       binRight = xmax;
328       ierr = PetscDrawRectangle(draw,binLeft,ymin,binRight,bins[0],bcolor,bcolor,bcolor,bcolor);CHKERRQ(ierr);
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       if (color == PETSC_DRAW_ROTATE && bins[0] != 0.0) bcolor++;
333       if (bcolor > PETSC_DRAW_BASIC_COLORS-1) bcolor = PETSC_DRAW_BLACK+1;
334     }
335     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
336   } else {
337     numBins    = hist->numBins;
338     numBinsOld = hist->numBins;
339     if (hist->integerBins && (((int) xmax - xmin) + 1.0e-05 > xmax - xmin)) {
340       initSize = (int) ((int) xmax - xmin)/numBins;
341       while (initSize*numBins != (int) xmax - xmin) {
342         initSize = PetscMax(initSize - 1, 1);
343         numBins  = (int) ((int) xmax - xmin)/initSize;
344         ierr     = PetscDrawHGSetNumberBins(hist, numBins);CHKERRQ(ierr);
345       }
346     }
347     binSize = (xmax - xmin)/numBins;
348     bins    = hist->bins;
349 
350     ierr = PetscMemzero(bins, numBins * sizeof(PetscReal));CHKERRQ(ierr);
351 
352     maxHeight = 0.0;
353     for (i = 0; i < numBins; i++) {
354       binLeft  = xmin + binSize*i;
355       binRight = xmin + binSize*(i+1);
356       for (p = 0; p < numValues; p++) {
357         if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
358         /* Handle last bin separately */
359         if ((i == numBins-1) && (values[p] == binRight)) bins[i]++;
360         if (!i) {
361           mean += values[p];
362           var  += values[p]*values[p];
363         }
364       }
365       maxHeight = PetscMax(maxHeight, bins[i]);
366     }
367     if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
368 
369     ierr = PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax);CHKERRQ(ierr);
370     if (hist->calcStats) {
371       mean /= numValues;
372       if (numValues > 1) var = (var - numValues*mean*mean) / (numValues-1);
373       else var = 0.0;
374       ierr = PetscSNPrintf(title, 256,"Mean: %g  Var: %g", (double)mean, (double)var);CHKERRQ(ierr);
375       ierr = PetscSNPrintf(xlabel,256, "Total: %D", numValues);CHKERRQ(ierr);
376       ierr = PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL);CHKERRQ(ierr);
377     }
378     ierr = PetscDrawAxisDraw(hist->axis);CHKERRQ(ierr);
379     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
380     if (!rank) { /* Draw bins */
381       for (i = 0; i < numBins; i++) {
382         binLeft  = xmin + binSize*i;
383         binRight = xmin + binSize*(i+1);
384         ierr = PetscDrawRectangle(draw,binLeft,ymin,binRight,bins[i],bcolor,bcolor,bcolor,bcolor);CHKERRQ(ierr);
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         if (color == PETSC_DRAW_ROTATE && bins[i]) bcolor++;
389         if (bcolor > PETSC_DRAW_BASIC_COLORS-1) bcolor = PETSC_DRAW_BLACK+1;
390       }
391     }
392     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
393     ierr = PetscDrawHGSetNumberBins(hist,numBinsOld);CHKERRQ(ierr);
394   }
395 
396   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
397   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
398   PetscFunctionReturn(0);
399 }
400 
401 #undef __FUNCT__
402 #define __FUNCT__ "PetscDrawHGSave"
403 /*@
404   PetscDrawHGSave - Saves a drawn image
405 
406   Collective on PetscDrawHG
407 
408   Input Parameter:
409 . hist - The histogram context
410 
411   Level: intermediate
412 
413   Concepts: histogram^saving
414 
415 .seealso:  PetscDrawHGCreate(), PetscDrawHGGetDraw(), PetscDrawSetSave(), PetscDrawSave()
416 @*/
417 PetscErrorCode  PetscDrawHGSave(PetscDrawHG hg)
418 {
419   PetscErrorCode ierr;
420 
421   PetscFunctionBegin;
422   PetscValidHeaderSpecific(hg,PETSC_DRAWHG_CLASSID,1);
423   ierr = PetscDrawSave(hg->win);CHKERRQ(ierr);
424   PetscFunctionReturn(0);
425 }
426 
427 #undef __FUNCT__
428 #define __FUNCT__ "PetscDrawHGView"
429 /*@
430   PetscDrawHGView - Prints the histogram information.
431 
432   Not collective
433 
434   Input Parameter:
435 . hist - The histogram context
436 
437   Level: beginner
438 
439 .keywords:  draw, histogram
440 @*/
441 PetscErrorCode  PetscDrawHGView(PetscDrawHG hist,PetscViewer viewer)
442 {
443   PetscReal      xmax,xmin,*bins,*values,binSize,binLeft,binRight,mean,var;
444   PetscErrorCode ierr;
445   PetscInt       numBins,numBinsOld,numValues,initSize,i,p;
446 
447   PetscFunctionBegin;
448   PetscValidHeaderSpecific(hist,PETSC_DRAWHG_CLASSID,1);
449 
450   if ((hist->xmin > hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(0);
451   if (hist->numValues < 1) PetscFunctionReturn(0);
452 
453   if (!viewer){
454     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)hist),&viewer);CHKERRQ(ierr);
455   }
456   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)hist,viewer);CHKERRQ(ierr);
457   xmax      = hist->xmax;
458   xmin      = hist->xmin;
459   numValues = hist->numValues;
460   values    = hist->values;
461   mean      = 0.0;
462   var       = 0.0;
463   if (xmax == xmin) {
464     /* Calculate number of points in the bin */
465     bins    = hist->bins;
466     bins[0] = 0.;
467     for (p = 0; p < numValues; p++) {
468       if (values[p] == xmin) bins[0]++;
469       mean += values[p];
470       var  += values[p]*values[p];
471     }
472     /* Draw bins */
473     ierr = PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", 0, (double)xmin, (double)xmax, (double)bins[0]);CHKERRQ(ierr);
474   } else {
475     numBins    = hist->numBins;
476     numBinsOld = hist->numBins;
477     if (hist->integerBins && (((int) xmax - xmin) + 1.0e-05 > xmax - xmin)) {
478       initSize = (int) ((int) xmax - xmin)/numBins;
479       while (initSize*numBins != (int) xmax - xmin) {
480         initSize = PetscMax(initSize - 1, 1);
481         numBins  = (int) ((int) xmax - xmin)/initSize;
482         ierr     = PetscDrawHGSetNumberBins(hist, numBins);CHKERRQ(ierr);
483       }
484     }
485     binSize = (xmax - xmin)/numBins;
486     bins    = hist->bins;
487 
488     /* Calculate number of points in each bin */
489     ierr = PetscMemzero(bins, numBins * sizeof(PetscReal));CHKERRQ(ierr);
490     for (i = 0; i < numBins; i++) {
491       binLeft  = xmin + binSize*i;
492       binRight = xmin + binSize*(i+1);
493       for (p = 0; p < numValues; p++) {
494         if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
495         /* Handle last bin separately */
496         if ((i == numBins-1) && (values[p] == binRight)) bins[i]++;
497         if (!i) {
498           mean += values[p];
499           var  += values[p]*values[p];
500         }
501       }
502     }
503     /* Draw bins */
504     for (i = 0; i < numBins; i++) {
505       binLeft  = xmin + binSize*i;
506       binRight = xmin + binSize*(i+1);
507       ierr = PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", (int)i, (double)binLeft, (double)binRight, (double)bins[i]);CHKERRQ(ierr);
508     }
509     ierr = PetscDrawHGSetNumberBins(hist, numBinsOld);CHKERRQ(ierr);
510   }
511 
512   if (hist->calcStats) {
513     mean /= numValues;
514     if (numValues > 1) var = (var - numValues*mean*mean) / (numValues-1);
515     else var = 0.0;
516     ierr = PetscViewerASCIIPrintf(viewer, "Mean: %g  Var: %g\n", (double)mean, (double)var);CHKERRQ(ierr);
517     ierr = PetscViewerASCIIPrintf(viewer, "Total: %D\n", numValues);CHKERRQ(ierr);
518   }
519   PetscFunctionReturn(0);
520 }
521 
522 #undef __FUNCT__
523 #define __FUNCT__ "PetscDrawHGSetColor"
524 /*@
525   PetscDrawHGSetColor - Sets the color the bars will be drawn with.
526 
527   Logically Collective on PetscDrawHG
528 
529   Input Parameters:
530 + hist - The histogram context
531 - color - one of the colors defined in petscdraw.h or PETSC_DRAW_ROTATE to make each bar a
532           different color
533 
534   Level: intermediate
535 
536 @*/
537 PetscErrorCode  PetscDrawHGSetColor(PetscDrawHG hist,int color)
538 {
539   PetscFunctionBegin;
540   PetscValidHeaderSpecific(hist,PETSC_DRAWHG_CLASSID,1);
541 
542   hist->color = color;
543   PetscFunctionReturn(0);
544 }
545 
546 #undef __FUNCT__
547 #define __FUNCT__ "PetscDrawHGSetLimits"
548 /*@
549   PetscDrawHGSetLimits - Sets the axis limits for a histogram. If more
550   points are added after this call, the limits will be adjusted to
551   include those additional points.
552 
553   Logically Collective on PetscDrawHG
554 
555   Input Parameters:
556 + hist - The histogram context
557 - x_min,x_max,y_min,y_max - The limits
558 
559   Level: intermediate
560 
561   Concepts: histogram^setting axis
562 @*/
563 PetscErrorCode  PetscDrawHGSetLimits(PetscDrawHG hist, PetscReal x_min, PetscReal x_max, int y_min, int y_max)
564 {
565   PetscFunctionBegin;
566   PetscValidHeaderSpecific(hist,PETSC_DRAWHG_CLASSID,1);
567 
568   hist->xmin = x_min;
569   hist->xmax = x_max;
570   hist->ymin = y_min;
571   hist->ymax = y_max;
572   PetscFunctionReturn(0);
573 }
574 
575 #undef __FUNCT__
576 #define __FUNCT__ "PetscDrawHGCalcStats"
577 /*@
578   PetscDrawHGCalcStats - Turns on calculation of descriptive statistics
579 
580   Not collective
581 
582   Input Parameters:
583 + hist - The histogram context
584 - calc - Flag for calculation
585 
586   Level: intermediate
587 
588 .keywords:  draw, histogram, statistics
589 
590 @*/
591 PetscErrorCode  PetscDrawHGCalcStats(PetscDrawHG hist, PetscBool calc)
592 {
593   PetscFunctionBegin;
594   PetscValidHeaderSpecific(hist,PETSC_DRAWHG_CLASSID,1);
595 
596   hist->calcStats = calc;
597   PetscFunctionReturn(0);
598 }
599 
600 #undef __FUNCT__
601 #define __FUNCT__ "PetscDrawHGIntegerBins"
602 /*@
603   PetscDrawHGIntegerBins - Turns on integer width bins
604 
605   Not collective
606 
607   Input Parameters:
608 + hist - The histogram context
609 - ints - Flag for integer width bins
610 
611   Level: intermediate
612 
613 .keywords:  draw, histogram, statistics
614 @*/
615 PetscErrorCode  PetscDrawHGIntegerBins(PetscDrawHG hist, PetscBool ints)
616 {
617   PetscFunctionBegin;
618   PetscValidHeaderSpecific(hist,PETSC_DRAWHG_CLASSID,1);
619 
620   hist->integerBins = ints;
621   PetscFunctionReturn(0);
622 }
623 
624 #undef __FUNCT__
625 #define __FUNCT__ "PetscDrawHGGetAxis"
626 /*@C
627   PetscDrawHGGetAxis - Gets the axis context associated with a histogram.
628   This is useful if one wants to change some axis property, such as
629   labels, color, etc. The axis context should not be destroyed by the
630   application code.
631 
632   Not Collective, PetscDrawAxis is parallel if PetscDrawHG is parallel
633 
634   Input Parameter:
635 . hist - The histogram context
636 
637   Output Parameter:
638 . axis - The axis context
639 
640   Level: intermediate
641 
642 @*/
643 PetscErrorCode  PetscDrawHGGetAxis(PetscDrawHG hist,PetscDrawAxis *axis)
644 {
645   PetscFunctionBegin;
646   PetscValidHeaderSpecific(hist,PETSC_DRAWHG_CLASSID,1);
647   PetscValidPointer(axis,2);
648   *axis = hist->axis;
649   PetscFunctionReturn(0);
650 }
651 
652 #undef __FUNCT__
653 #define __FUNCT__ "PetscDrawHGGetDraw"
654 /*@C
655   PetscDrawHGGetDraw - Gets the draw context associated with a histogram.
656 
657   Not Collective, PetscDraw is parallel if PetscDrawHG is parallel
658 
659   Input Parameter:
660 . hist - The histogram context
661 
662   Output Parameter:
663 . draw  - The draw context
664 
665   Level: intermediate
666 
667 @*/
668 PetscErrorCode  PetscDrawHGGetDraw(PetscDrawHG hist,PetscDraw *draw)
669 {
670   PetscFunctionBegin;
671   PetscValidHeaderSpecific(hist,PETSC_DRAWHG_CLASSID,1);
672   PetscValidPointer(draw,2);
673   *draw = hist->win;
674   PetscFunctionReturn(0);
675 }
676 
677