xref: /petsc/src/sys/classes/draw/utils/hists.c (revision 075987266ca0d0e8d09d008387b2c5b96849a557)
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     }
333     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
334   } else {
335     numBins    = hist->numBins;
336     numBinsOld = hist->numBins;
337     if (hist->integerBins && (((int) xmax - xmin) + 1.0e-05 > xmax - xmin)) {
338       initSize = (int) ((int) xmax - xmin)/numBins;
339       while (initSize*numBins != (int) xmax - xmin) {
340         initSize = PetscMax(initSize - 1, 1);
341         numBins  = (int) ((int) xmax - xmin)/initSize;
342         ierr     = PetscDrawHGSetNumberBins(hist, numBins);CHKERRQ(ierr);
343       }
344     }
345     binSize = (xmax - xmin)/numBins;
346     bins    = hist->bins;
347 
348     ierr = PetscMemzero(bins, numBins * sizeof(PetscReal));CHKERRQ(ierr);
349 
350     maxHeight = 0.0;
351     for (i = 0; i < numBins; i++) {
352       binLeft  = xmin + binSize*i;
353       binRight = xmin + binSize*(i+1);
354       for (p = 0; p < numValues; p++) {
355         if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
356         /* Handle last bin separately */
357         if ((i == numBins-1) && (values[p] == binRight)) bins[i]++;
358         if (!i) {
359           mean += values[p];
360           var  += values[p]*values[p];
361         }
362       }
363       maxHeight = PetscMax(maxHeight, bins[i]);
364     }
365     if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
366 
367     ierr = PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax);CHKERRQ(ierr);
368     if (hist->calcStats) {
369       mean /= numValues;
370       if (numValues > 1) var = (var - numValues*mean*mean) / (numValues-1);
371       else var = 0.0;
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     ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
378     if (!rank) { /* Draw bins */
379       for (i = 0; i < numBins; i++) {
380         binLeft  = xmin + binSize*i;
381         binRight = xmin + binSize*(i+1);
382         ierr = PetscDrawRectangle(draw,binLeft,ymin,binRight,bins[i],bcolor,bcolor,bcolor,bcolor);CHKERRQ(ierr);
383         ierr = PetscDrawLine(draw,binLeft,ymin,binLeft,bins[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
384         ierr = PetscDrawLine(draw,binRight,ymin,binRight,bins[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
385         ierr = PetscDrawLine(draw,binLeft,bins[i],binRight,bins[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
386         if (color == PETSC_DRAW_ROTATE && bins[i]) bcolor++;
387         if (bcolor > PETSC_DRAW_BASIC_COLORS-1) bcolor = PETSC_DRAW_BLACK+1;
388       }
389     }
390     ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
391     ierr = PetscDrawHGSetNumberBins(hist,numBinsOld);CHKERRQ(ierr);
392   }
393 
394   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
395   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
396   PetscFunctionReturn(0);
397 }
398 
399 #undef __FUNCT__
400 #define __FUNCT__ "PetscDrawHGSave"
401 /*@
402   PetscDrawHGSave - Saves a drawn image
403 
404   Collective on PetscDrawHG
405 
406   Input Parameter:
407 . hist - The histogram context
408 
409   Level: intermediate
410 
411   Concepts: histogram^saving
412 
413 .seealso:  PetscDrawHGCreate(), PetscDrawHGGetDraw(), PetscDrawSetSave(), PetscDrawSave()
414 @*/
415 PetscErrorCode  PetscDrawHGSave(PetscDrawHG hg)
416 {
417   PetscErrorCode ierr;
418 
419   PetscFunctionBegin;
420   PetscValidHeaderSpecific(hg,PETSC_DRAWHG_CLASSID,1);
421   ierr = PetscDrawSave(hg->win);CHKERRQ(ierr);
422   PetscFunctionReturn(0);
423 }
424 
425 #undef __FUNCT__
426 #define __FUNCT__ "PetscDrawHGView"
427 /*@
428   PetscDrawHGView - Prints the histogram information.
429 
430   Not collective
431 
432   Input Parameter:
433 . hist - The histogram context
434 
435   Level: beginner
436 
437 .keywords:  draw, histogram
438 @*/
439 PetscErrorCode  PetscDrawHGView(PetscDrawHG hist,PetscViewer viewer)
440 {
441   PetscReal      xmax,xmin,*bins,*values,binSize,binLeft,binRight,mean,var;
442   PetscErrorCode ierr;
443   PetscInt       numBins,numBinsOld,numValues,initSize,i,p;
444 
445   PetscFunctionBegin;
446   PetscValidHeaderSpecific(hist,PETSC_DRAWHG_CLASSID,1);
447 
448   if ((hist->xmin > hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(0);
449   if (hist->numValues < 1) PetscFunctionReturn(0);
450 
451   if (!viewer){
452     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)hist),&viewer);CHKERRQ(ierr);
453   }
454   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)hist,viewer);CHKERRQ(ierr);
455   xmax      = hist->xmax;
456   xmin      = hist->xmin;
457   numValues = hist->numValues;
458   values    = hist->values;
459   mean      = 0.0;
460   var       = 0.0;
461   if (xmax == xmin) {
462     /* Calculate number of points in the bin */
463     bins    = hist->bins;
464     bins[0] = 0.;
465     for (p = 0; p < numValues; p++) {
466       if (values[p] == xmin) bins[0]++;
467       mean += values[p];
468       var  += values[p]*values[p];
469     }
470     /* Draw bins */
471     ierr = PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", 0, (double)xmin, (double)xmax, (double)bins[0]);CHKERRQ(ierr);
472   } else {
473     numBins    = hist->numBins;
474     numBinsOld = hist->numBins;
475     if (hist->integerBins && (((int) xmax - xmin) + 1.0e-05 > xmax - xmin)) {
476       initSize = (int) ((int) xmax - xmin)/numBins;
477       while (initSize*numBins != (int) xmax - xmin) {
478         initSize = PetscMax(initSize - 1, 1);
479         numBins  = (int) ((int) xmax - xmin)/initSize;
480         ierr     = PetscDrawHGSetNumberBins(hist, numBins);CHKERRQ(ierr);
481       }
482     }
483     binSize = (xmax - xmin)/numBins;
484     bins    = hist->bins;
485 
486     /* Calculate number of points in each bin */
487     ierr = PetscMemzero(bins, numBins * sizeof(PetscReal));CHKERRQ(ierr);
488     for (i = 0; i < numBins; i++) {
489       binLeft  = xmin + binSize*i;
490       binRight = xmin + binSize*(i+1);
491       for (p = 0; p < numValues; p++) {
492         if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
493         /* Handle last bin separately */
494         if ((i == numBins-1) && (values[p] == binRight)) bins[i]++;
495         if (!i) {
496           mean += values[p];
497           var  += values[p]*values[p];
498         }
499       }
500     }
501     /* Draw bins */
502     for (i = 0; i < numBins; i++) {
503       binLeft  = xmin + binSize*i;
504       binRight = xmin + binSize*(i+1);
505       ierr = PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", (int)i, (double)binLeft, (double)binRight, (double)bins[i]);CHKERRQ(ierr);
506     }
507     ierr = PetscDrawHGSetNumberBins(hist, numBinsOld);CHKERRQ(ierr);
508   }
509 
510   if (hist->calcStats) {
511     mean /= numValues;
512     if (numValues > 1) var = (var - numValues*mean*mean) / (numValues-1);
513     else var = 0.0;
514     ierr = PetscViewerASCIIPrintf(viewer, "Mean: %g  Var: %g\n", (double)mean, (double)var);CHKERRQ(ierr);
515     ierr = PetscViewerASCIIPrintf(viewer, "Total: %D\n", numValues);CHKERRQ(ierr);
516   }
517   PetscFunctionReturn(0);
518 }
519 
520 #undef __FUNCT__
521 #define __FUNCT__ "PetscDrawHGSetColor"
522 /*@
523   PetscDrawHGSetColor - Sets the color the bars will be drawn with.
524 
525   Logically Collective on PetscDrawHG
526 
527   Input Parameters:
528 + hist - The histogram context
529 - color - one of the colors defined in petscdraw.h or PETSC_DRAW_ROTATE to make each bar a
530           different color
531 
532   Level: intermediate
533 
534 @*/
535 PetscErrorCode  PetscDrawHGSetColor(PetscDrawHG hist,int color)
536 {
537   PetscFunctionBegin;
538   PetscValidHeaderSpecific(hist,PETSC_DRAWHG_CLASSID,1);
539 
540   hist->color = color;
541   PetscFunctionReturn(0);
542 }
543 
544 #undef __FUNCT__
545 #define __FUNCT__ "PetscDrawHGSetLimits"
546 /*@
547   PetscDrawHGSetLimits - Sets the axis limits for a histogram. If more
548   points are added after this call, the limits will be adjusted to
549   include those additional points.
550 
551   Logically Collective on PetscDrawHG
552 
553   Input Parameters:
554 + hist - The histogram context
555 - x_min,x_max,y_min,y_max - The limits
556 
557   Level: intermediate
558 
559   Concepts: histogram^setting axis
560 @*/
561 PetscErrorCode  PetscDrawHGSetLimits(PetscDrawHG hist, PetscReal x_min, PetscReal x_max, int y_min, int y_max)
562 {
563   PetscFunctionBegin;
564   PetscValidHeaderSpecific(hist,PETSC_DRAWHG_CLASSID,1);
565 
566   hist->xmin = x_min;
567   hist->xmax = x_max;
568   hist->ymin = y_min;
569   hist->ymax = y_max;
570   PetscFunctionReturn(0);
571 }
572 
573 #undef __FUNCT__
574 #define __FUNCT__ "PetscDrawHGCalcStats"
575 /*@
576   PetscDrawHGCalcStats - Turns on calculation of descriptive statistics
577 
578   Not collective
579 
580   Input Parameters:
581 + hist - The histogram context
582 - calc - Flag for calculation
583 
584   Level: intermediate
585 
586 .keywords:  draw, histogram, statistics
587 
588 @*/
589 PetscErrorCode  PetscDrawHGCalcStats(PetscDrawHG hist, PetscBool calc)
590 {
591   PetscFunctionBegin;
592   PetscValidHeaderSpecific(hist,PETSC_DRAWHG_CLASSID,1);
593 
594   hist->calcStats = calc;
595   PetscFunctionReturn(0);
596 }
597 
598 #undef __FUNCT__
599 #define __FUNCT__ "PetscDrawHGIntegerBins"
600 /*@
601   PetscDrawHGIntegerBins - Turns on integer width bins
602 
603   Not collective
604 
605   Input Parameters:
606 + hist - The histogram context
607 - ints - Flag for integer width bins
608 
609   Level: intermediate
610 
611 .keywords:  draw, histogram, statistics
612 @*/
613 PetscErrorCode  PetscDrawHGIntegerBins(PetscDrawHG hist, PetscBool ints)
614 {
615   PetscFunctionBegin;
616   PetscValidHeaderSpecific(hist,PETSC_DRAWHG_CLASSID,1);
617 
618   hist->integerBins = ints;
619   PetscFunctionReturn(0);
620 }
621 
622 #undef __FUNCT__
623 #define __FUNCT__ "PetscDrawHGGetAxis"
624 /*@C
625   PetscDrawHGGetAxis - Gets the axis context associated with a histogram.
626   This is useful if one wants to change some axis property, such as
627   labels, color, etc. The axis context should not be destroyed by the
628   application code.
629 
630   Not Collective, PetscDrawAxis is parallel if PetscDrawHG is parallel
631 
632   Input Parameter:
633 . hist - The histogram context
634 
635   Output Parameter:
636 . axis - The axis context
637 
638   Level: intermediate
639 
640 @*/
641 PetscErrorCode  PetscDrawHGGetAxis(PetscDrawHG hist,PetscDrawAxis *axis)
642 {
643   PetscFunctionBegin;
644   PetscValidHeaderSpecific(hist,PETSC_DRAWHG_CLASSID,1);
645   PetscValidPointer(axis,2);
646   *axis = hist->axis;
647   PetscFunctionReturn(0);
648 }
649 
650 #undef __FUNCT__
651 #define __FUNCT__ "PetscDrawHGGetDraw"
652 /*@C
653   PetscDrawHGGetDraw - Gets the draw context associated with a histogram.
654 
655   Not Collective, PetscDraw is parallel if PetscDrawHG is parallel
656 
657   Input Parameter:
658 . hist - The histogram context
659 
660   Output Parameter:
661 . draw  - The draw context
662 
663   Level: intermediate
664 
665 @*/
666 PetscErrorCode  PetscDrawHGGetDraw(PetscDrawHG hist,PetscDraw *draw)
667 {
668   PetscFunctionBegin;
669   PetscValidHeaderSpecific(hist,PETSC_DRAWHG_CLASSID,1);
670   PetscValidPointer(draw,2);
671   *draw = hist->win;
672   PetscFunctionReturn(0);
673 }
674 
675