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