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