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