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