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