Actual source code: hists.c

  1: /*
  2:   Contains the data structure for plotting a histogram in a window with an axis.
  3: */
  4: #include <petscdraw.h>
  5: #include <petsc/private/petscimpl.h>
  6: #include <petscviewer.h>

  8: PetscClassId PETSC_DRAWHG_CLASSID = 0;

 10: struct _p_PetscDrawHG {
 11:   PETSCHEADER(int);
 12:   PetscErrorCode (*destroy)(PetscDrawSP);
 13:   PetscErrorCode (*view)(PetscDrawSP, PetscViewer);
 14:   PetscDraw     win;
 15:   PetscDrawAxis axis;
 16:   PetscReal     xmin, xmax;
 17:   PetscReal     ymin, ymax;
 18:   int           numBins;
 19:   int           maxBins;
 20:   PetscReal    *bins;
 21:   int           numValues;
 22:   int           maxValues;
 23:   PetscReal    *values;
 24:   int           color;
 25:   PetscBool     calcStats;
 26:   PetscBool     integerBins;
 27: };

 29: #define CHUNKSIZE 100

 31: /*@
 32:   PetscDrawHGCreate - Creates a histogram data structure.

 34:   Collective

 36:   Input Parameters:
 37: + draw - The window where the graph will be made
 38: - bins - The number of bins to use

 40:   Output Parameter:
 41: . hist - The histogram context

 43:   Level: intermediate

 45:   Notes:
 46:   The difference between a bar chart, `PetscDrawBar`, and a histogram, `PetscDrawHG`, is explained here <https://stattrek.com/statistics/charts/histogram.aspx?Tutorial=AP>

 48:   The histogram is only displayed when `PetscDrawHGDraw()` is called.

 50:   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
 51:   zeroth MPI process in the communicator. All MPI processes in the communicator must call `PetscDrawHGDraw()` to display the updated graph.

 53: .seealso: `PetscDrawHGDestroy()`, `PetscDrawHG`, `PetscDrawBarCreate()`, `PetscDrawBar`, `PetscDrawLGCreate()`, `PetscDrawLG`, `PetscDrawSPCreate()`, `PetscDrawSP`,
 54:           `PetscDrawHGSetNumberBins()`, `PetscDrawHGReset()`, `PetscDrawHGAddValue()`, `PetscDrawHGDraw()`, `PetscDrawHGSave()`, `PetscDrawHGView()`, `PetscDrawHGSetColor()`,
 55:           `PetscDrawHGSetLimits()`, `PetscDrawHGCalcStats()`, `PetscDrawHGIntegerBins()`, `PetscDrawHGGetAxis()`, `PetscDrawAxis`, `PetscDrawHGGetDraw()`
 56: @*/
 57: PetscErrorCode PetscDrawHGCreate(PetscDraw draw, int bins, PetscDrawHG *hist)
 58: {
 59:   PetscDrawHG h;

 61:   PetscFunctionBegin;
 64:   PetscAssertPointer(hist, 3);

 66:   PetscCall(PetscHeaderCreate(h, PETSC_DRAWHG_CLASSID, "DrawHG", "Histogram", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawHGDestroy, NULL));
 67:   PetscCall(PetscObjectReference((PetscObject)draw));
 68:   h->win     = draw;
 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:   PetscCall(PetscMalloc1(h->maxBins, &h->bins));
 79:   h->numValues   = 0;
 80:   h->maxValues   = CHUNKSIZE;
 81:   h->calcStats   = PETSC_FALSE;
 82:   h->integerBins = PETSC_FALSE;
 83:   PetscCall(PetscMalloc1(h->maxValues, &h->values));
 84:   PetscCall(PetscDrawAxisCreate(draw, &h->axis));
 85:   *hist = h;
 86:   PetscFunctionReturn(PETSC_SUCCESS);
 87: }

 89: /*@
 90:   PetscDrawHGSetNumberBins - Change the number of bins that are to be drawn in the histogram

 92:   Logically Collective

 94:   Input Parameters:
 95: + hist - The histogram context.
 96: - bins - The number of bins.

 98:   Level: intermediate

100: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGIntegerBins()`
101: @*/
102: PetscErrorCode PetscDrawHGSetNumberBins(PetscDrawHG hist, int bins)
103: {
104:   PetscFunctionBegin;

108:   if (hist->maxBins < bins) {
109:     PetscCall(PetscFree(hist->bins));
110:     PetscCall(PetscMalloc1(bins, &hist->bins));
111:     hist->maxBins = bins;
112:   }
113:   hist->numBins = bins;
114:   PetscFunctionReturn(PETSC_SUCCESS);
115: }

117: /*@
118:   PetscDrawHGReset - Clears histogram to allow for reuse with new data.

120:   Logically Collective

122:   Input Parameter:
123: . hist - The histogram context.

125:   Level: intermediate

127: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`
128: @*/
129: PetscErrorCode PetscDrawHGReset(PetscDrawHG hist)
130: {
131:   PetscFunctionBegin;

134:   hist->xmin      = PETSC_MAX_REAL;
135:   hist->xmax      = PETSC_MIN_REAL;
136:   hist->ymin      = 0.0;
137:   hist->ymax      = 1.0;
138:   hist->numValues = 0;
139:   PetscFunctionReturn(PETSC_SUCCESS);
140: }

142: /*@
143:   PetscDrawHGDestroy - Frees all space taken up by histogram data structure.

145:   Collective

147:   Input Parameter:
148: . hist - The histogram context

150:   Level: intermediate

152: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`
153: @*/
154: PetscErrorCode PetscDrawHGDestroy(PetscDrawHG *hist)
155: {
156:   PetscFunctionBegin;
157:   if (!*hist) PetscFunctionReturn(PETSC_SUCCESS);
159:   if (--((PetscObject)*hist)->refct > 0) {
160:     *hist = NULL;
161:     PetscFunctionReturn(PETSC_SUCCESS);
162:   }

164:   PetscCall(PetscFree((*hist)->bins));
165:   PetscCall(PetscFree((*hist)->values));
166:   PetscCall(PetscDrawAxisDestroy(&(*hist)->axis));
167:   PetscCall(PetscDrawDestroy(&(*hist)->win));
168:   PetscCall(PetscHeaderDestroy(hist));
169:   PetscFunctionReturn(PETSC_SUCCESS);
170: }

172: /*@
173:   PetscDrawHGAddValue - Adds another value to the histogram.

175:   Logically Collective

177:   Input Parameters:
178: + hist  - The histogram
179: - value - The value

181:   Level: intermediate

183: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGReset()`
184: @*/
185: PetscErrorCode PetscDrawHGAddValue(PetscDrawHG hist, PetscReal value)
186: {
187:   PetscFunctionBegin;

190:   /* Allocate more memory if necessary */
191:   if (hist->numValues >= hist->maxValues) {
192:     PetscReal *tmp;

194:     PetscCall(PetscMalloc1(hist->maxValues + CHUNKSIZE, &tmp));
195:     PetscCall(PetscArraycpy(tmp, hist->values, hist->maxValues));
196:     PetscCall(PetscFree(hist->values));

198:     hist->values = tmp;
199:     hist->maxValues += CHUNKSIZE;
200:   }
201:   /* I disagree with the original Petsc implementation here. There should be no overshoot, but rather the
202:      stated convention of using half-open intervals (always the way to go) */
203:   if (!hist->numValues && (hist->xmin == PETSC_MAX_REAL) && (hist->xmax == PETSC_MIN_REAL)) {
204:     hist->xmin = value;
205:     hist->xmax = value;
206: #if 1
207:   } else {
208:     /* Update limits */
209:     if (value > hist->xmax) hist->xmax = value;
210:     if (value < hist->xmin) hist->xmin = value;
211: #else
212:   } else if (hist->numValues == 1) {
213:     /* Update limits -- We need to overshoot the largest value somewhat */
214:     if (value > hist->xmax) hist->xmax = value + 0.001 * (value - hist->xmin) / (PetscReal)hist->numBins;
215:     if (value < hist->xmin) {
216:       hist->xmin = value;
217:       hist->xmax = hist->xmax + 0.001 * (hist->xmax - hist->xmin) / (PetscReal)hist->numBins;
218:     }
219:   } else {
220:     /* Update limits -- We need to overshoot the largest value somewhat */
221:     if (value > hist->xmax) hist->xmax = value + 0.001 * (hist->xmax - hist->xmin) / (PetscReal)hist->numBins;
222:     if (value < hist->xmin) hist->xmin = value;
223: #endif
224:   }

226:   hist->values[hist->numValues++] = value;
227:   PetscFunctionReturn(PETSC_SUCCESS);
228: }

230: /*@
231:   PetscDrawHGDraw - Redraws a histogram.

233:   Collective

235:   Input Parameter:
236: . hist - The histogram context

238:   Level: intermediate

240: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGAddValue()`, `PetscDrawHGReset()`
241: @*/
242: PetscErrorCode PetscDrawHGDraw(PetscDrawHG hist)
243: {
244:   PetscDraw   draw;
245:   PetscBool   isnull;
246:   PetscReal   xmin, xmax, ymin, ymax, *bins, *values, binSize, binLeft, binRight, maxHeight, mean, var;
247:   char        title[256];
248:   char        xlabel[256];
249:   PetscInt    numValues, initSize, i, p;
250:   int         bcolor, color, numBins, numBinsOld;
251:   PetscMPIInt rank;

253:   PetscFunctionBegin;
255:   PetscCall(PetscDrawIsNull(hist->win, &isnull));
256:   if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
257:   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)hist), &rank));

259:   if ((hist->xmin >= hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(PETSC_SUCCESS);
260:   if (hist->numValues < 1) PetscFunctionReturn(PETSC_SUCCESS);

262:   color = hist->color;
263:   if (color == PETSC_DRAW_ROTATE) bcolor = PETSC_DRAW_BLACK + 1;
264:   else bcolor = color;

266:   xmin      = hist->xmin;
267:   xmax      = hist->xmax;
268:   ymin      = hist->ymin;
269:   ymax      = hist->ymax;
270:   numValues = hist->numValues;
271:   values    = hist->values;
272:   mean      = 0.0;
273:   var       = 0.0;

275:   draw = hist->win;
276:   PetscCall(PetscDrawCheckResizedWindow(draw));
277:   PetscCall(PetscDrawClear(draw));

279:   if (xmin == xmax) {
280:     /* Calculate number of points in each bin */
281:     bins    = hist->bins;
282:     bins[0] = 0.;
283:     for (p = 0; p < numValues; p++) {
284:       if (values[p] == xmin) bins[0]++;
285:       mean += values[p];
286:       var += values[p] * values[p];
287:     }
288:     maxHeight = bins[0];
289:     if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
290:     xmax = xmin + 1;
291:     PetscCall(PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax));
292:     if (hist->calcStats) {
293:       mean /= (PetscReal)numValues;
294:       if (numValues > 1) var = (var - ((PetscReal)numValues) * mean * mean) / ((PetscReal)numValues - 1);
295:       else var = 0.0;
296:       PetscCall(PetscSNPrintf(title, 256, "Mean: %g  Var: %g", (double)mean, (double)var));
297:       PetscCall(PetscSNPrintf(xlabel, 256, "Total: %" PetscInt_FMT, numValues));
298:       PetscCall(PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL));
299:     }
300:     PetscCall(PetscDrawAxisDraw(hist->axis));
301:     PetscDrawCollectiveBegin(draw);
302:     if (rank == 0) { /* Draw bins */
303:       binLeft  = xmin;
304:       binRight = xmax;
305:       PetscCall(PetscDrawRectangle(draw, binLeft, ymin, binRight, bins[0], bcolor, bcolor, bcolor, bcolor));
306:       PetscCall(PetscDrawLine(draw, binLeft, ymin, binLeft, bins[0], PETSC_DRAW_BLACK));
307:       PetscCall(PetscDrawLine(draw, binRight, ymin, binRight, bins[0], PETSC_DRAW_BLACK));
308:       PetscCall(PetscDrawLine(draw, binLeft, bins[0], binRight, bins[0], PETSC_DRAW_BLACK));
309:     }
310:     PetscDrawCollectiveEnd(draw);
311:   } else {
312:     numBins    = hist->numBins;
313:     numBinsOld = hist->numBins;
314:     if (hist->integerBins && (((int)xmax - xmin) + 1.0e-05 > xmax - xmin)) {
315:       initSize = ((int)(xmax - xmin)) / numBins;
316:       while (initSize * numBins != (int)xmax - xmin) {
317:         initSize = PetscMax(initSize - 1, 1);
318:         numBins  = ((int)(xmax - xmin)) / initSize;
319:         PetscCall(PetscDrawHGSetNumberBins(hist, numBins));
320:       }
321:     }
322:     binSize = (xmax - xmin) / (PetscReal)numBins;
323:     bins    = hist->bins;

325:     PetscCall(PetscArrayzero(bins, numBins));

327:     maxHeight = 0.0;
328:     for (i = 0; i < numBins; i++) {
329:       binLeft  = xmin + binSize * i;
330:       binRight = xmin + binSize * (i + 1);
331:       for (p = 0; p < numValues; p++) {
332:         if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
333:         /* Handle last bin separately */
334:         if ((i == numBins - 1) && (values[p] == binRight)) bins[i]++;
335:         if (!i) {
336:           mean += values[p];
337:           var += values[p] * values[p];
338:         }
339:       }
340:       maxHeight = PetscMax(maxHeight, bins[i]);
341:     }
342:     if (maxHeight > ymax) ymax = hist->ymax = maxHeight;

344:     PetscCall(PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax));
345:     if (hist->calcStats) {
346:       mean /= numValues;
347:       if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1);
348:       else var = 0.0;
349:       PetscCall(PetscSNPrintf(title, 256, "Mean: %g  Var: %g", (double)mean, (double)var));
350:       PetscCall(PetscSNPrintf(xlabel, 256, "Total: %" PetscInt_FMT, numValues));
351:       PetscCall(PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL));
352:     }
353:     PetscCall(PetscDrawAxisDraw(hist->axis));
354:     PetscDrawCollectiveBegin(draw);
355:     if (rank == 0) { /* Draw bins */
356:       for (i = 0; i < numBins; i++) {
357:         binLeft  = xmin + binSize * i;
358:         binRight = xmin + binSize * (i + 1);
359:         PetscCall(PetscDrawRectangle(draw, binLeft, ymin, binRight, bins[i], bcolor, bcolor, bcolor, bcolor));
360:         PetscCall(PetscDrawLine(draw, binLeft, ymin, binLeft, bins[i], PETSC_DRAW_BLACK));
361:         PetscCall(PetscDrawLine(draw, binRight, ymin, binRight, bins[i], PETSC_DRAW_BLACK));
362:         PetscCall(PetscDrawLine(draw, binLeft, bins[i], binRight, bins[i], PETSC_DRAW_BLACK));
363:         if (color == PETSC_DRAW_ROTATE && bins[i]) bcolor++;
364:         if (bcolor > PETSC_DRAW_BASIC_COLORS - 1) bcolor = PETSC_DRAW_BLACK + 1;
365:       }
366:     }
367:     PetscDrawCollectiveEnd(draw);
368:     PetscCall(PetscDrawHGSetNumberBins(hist, numBinsOld));
369:   }

371:   PetscCall(PetscDrawFlush(draw));
372:   PetscCall(PetscDrawPause(draw));
373:   PetscFunctionReturn(PETSC_SUCCESS);
374: }

376: /*@
377:   PetscDrawHGSave - Saves a drawn image

379:   Collective

381:   Input Parameter:
382: . hg - The histogram context

384:   Level: intermediate

386: .seealso: `PetscDrawSave()`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawHGDraw()`
387: @*/
388: PetscErrorCode PetscDrawHGSave(PetscDrawHG hg)
389: {
390:   PetscFunctionBegin;
392:   PetscCall(PetscDrawSave(hg->win));
393:   PetscFunctionReturn(PETSC_SUCCESS);
394: }

396: /*@
397:   PetscDrawHGView - Prints the histogram information to a viewer

399:   Not Collective

401:   Input Parameters:
402: + hist   - The histogram context
403: - viewer - The viewer to view it with

405:   Level: beginner

407: .seealso: `PetscDrawHG`, `PetscViewer`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`
408: @*/
409: PetscErrorCode PetscDrawHGView(PetscDrawHG hist, PetscViewer viewer)
410: {
411:   PetscReal xmax, xmin, *bins, *values, binSize, binLeft, binRight, mean, var;
412:   PetscInt  numBins, numBinsOld, numValues, initSize, i, p;
413:   int       inumBins;

415:   PetscFunctionBegin;

418:   if ((hist->xmin > hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(PETSC_SUCCESS);
419:   if (hist->numValues < 1) PetscFunctionReturn(PETSC_SUCCESS);

421:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)hist), &viewer));
422:   PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)hist, viewer));
423:   xmax      = hist->xmax;
424:   xmin      = hist->xmin;
425:   numValues = hist->numValues;
426:   values    = hist->values;
427:   mean      = 0.0;
428:   var       = 0.0;
429:   if (xmax == xmin) {
430:     /* Calculate number of points in the bin */
431:     bins    = hist->bins;
432:     bins[0] = 0.;
433:     for (p = 0; p < numValues; p++) {
434:       if (values[p] == xmin) bins[0]++;
435:       mean += values[p];
436:       var += values[p] * values[p];
437:     }
438:     /* Draw bins */
439:     PetscCall(PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", 0, (double)xmin, (double)xmax, (double)bins[0]));
440:   } else {
441:     numBins    = hist->numBins;
442:     numBinsOld = hist->numBins;
443:     if (hist->integerBins && (((int)xmax - xmin) + 1.0e-05 > xmax - xmin)) {
444:       initSize = (int)((int)xmax - xmin) / numBins;
445:       while (initSize * numBins != (int)xmax - xmin) {
446:         initSize = PetscMax(initSize - 1, 1);
447:         numBins  = (int)((int)xmax - xmin) / initSize;
448:         PetscCall(PetscCIntCast(numBins, &inumBins));
449:         PetscCall(PetscDrawHGSetNumberBins(hist, inumBins));
450:       }
451:     }
452:     binSize = (xmax - xmin) / numBins;
453:     bins    = hist->bins;

455:     /* Calculate number of points in each bin */
456:     PetscCall(PetscArrayzero(bins, numBins));
457:     for (i = 0; i < numBins; i++) {
458:       binLeft  = xmin + binSize * i;
459:       binRight = xmin + binSize * (i + 1);
460:       for (p = 0; p < numValues; p++) {
461:         if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
462:         /* Handle last bin separately */
463:         if ((i == numBins - 1) && (values[p] == binRight)) bins[i]++;
464:         if (!i) {
465:           mean += values[p];
466:           var += values[p] * values[p];
467:         }
468:       }
469:     }
470:     /* Draw bins */
471:     for (i = 0; i < numBins; i++) {
472:       binLeft  = xmin + binSize * i;
473:       binRight = xmin + binSize * (i + 1);
474:       PetscCall(PetscViewerASCIIPrintf(viewer, "Bin %2" PetscInt_FMT " (%6.2g - %6.2g): %.0g\n", i, (double)binLeft, (double)binRight, (double)bins[i]));
475:     }
476:     PetscCall(PetscCIntCast(numBinsOld, &inumBins));
477:     PetscCall(PetscDrawHGSetNumberBins(hist, inumBins));
478:   }

480:   if (hist->calcStats) {
481:     mean /= numValues;
482:     if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1);
483:     else var = 0.0;
484:     PetscCall(PetscViewerASCIIPrintf(viewer, "Mean: %g  Var: %g\n", (double)mean, (double)var));
485:     PetscCall(PetscViewerASCIIPrintf(viewer, "Total: %" PetscInt_FMT "\n", numValues));
486:   }
487:   PetscFunctionReturn(PETSC_SUCCESS);
488: }

490: /*@
491:   PetscDrawHGSetColor - Sets the color the bars will be drawn with.

493:   Logically Collective

495:   Input Parameters:
496: + hist  - The histogram context
497: - color - one of the colors defined in petscdraw.h or `PETSC_DRAW_ROTATE` to make each bar a different color

499:   Level: intermediate

501: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`, `PetscDrawHGGetAxis()`
502: @*/
503: PetscErrorCode PetscDrawHGSetColor(PetscDrawHG hist, int color)
504: {
505:   PetscFunctionBegin;

508:   hist->color = color;
509:   PetscFunctionReturn(PETSC_SUCCESS);
510: }

512: /*@
513:   PetscDrawHGSetLimits - Sets the axis limits for a histogram. If more
514:   points are added after this call, the limits will be adjusted to
515:   include those additional points.

517:   Logically Collective

519:   Input Parameters:
520: + hist  - The histogram context
521: . x_min - the horizontal lower limit
522: . x_max - the horizontal upper limit
523: . y_min - the vertical lower limit
524: - y_max - the vertical upper limit

526:   Level: intermediate

528: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`, `PetscDrawHGGetAxis()`
529: @*/
530: PetscErrorCode PetscDrawHGSetLimits(PetscDrawHG hist, PetscReal x_min, PetscReal x_max, int y_min, int y_max)
531: {
532:   PetscFunctionBegin;

535:   hist->xmin = x_min;
536:   hist->xmax = x_max;
537:   hist->ymin = y_min;
538:   hist->ymax = y_max;
539:   PetscFunctionReturn(PETSC_SUCCESS);
540: }

542: /*@
543:   PetscDrawHGCalcStats - Turns on calculation of descriptive statistics associated with the histogram

545:   Not Collective

547:   Input Parameters:
548: + hist - The histogram context
549: - calc - Flag for calculation

551:   Level: intermediate

553: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`
554: @*/
555: PetscErrorCode PetscDrawHGCalcStats(PetscDrawHG hist, PetscBool calc)
556: {
557:   PetscFunctionBegin;

560:   hist->calcStats = calc;
561:   PetscFunctionReturn(PETSC_SUCCESS);
562: }

564: /*@
565:   PetscDrawHGIntegerBins - Turns on integer width bins

567:   Not Collective

569:   Input Parameters:
570: + hist - The histogram context
571: - ints - Flag for integer width bins

573:   Level: intermediate

575: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`
576: @*/
577: PetscErrorCode PetscDrawHGIntegerBins(PetscDrawHG hist, PetscBool ints)
578: {
579:   PetscFunctionBegin;

582:   hist->integerBins = ints;
583:   PetscFunctionReturn(PETSC_SUCCESS);
584: }

586: /*@
587:   PetscDrawHGGetAxis - Gets the axis context associated with a histogram.
588:   This is useful if one wants to change some axis property, such as
589:   labels, color, etc. The axis context should not be destroyed by the
590:   application code.

592:   Not Collective, axis is parallel if hist is parallel

594:   Input Parameter:
595: . hist - The histogram context

597:   Output Parameter:
598: . axis - The axis context

600:   Level: intermediate

602: .seealso: `PetscDrawHG`, `PetscDrawAxis`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`, `PetscDrawHGSetLimits()`
603: @*/
604: PetscErrorCode PetscDrawHGGetAxis(PetscDrawHG hist, PetscDrawAxis *axis)
605: {
606:   PetscFunctionBegin;
608:   PetscAssertPointer(axis, 2);
609:   *axis = hist->axis;
610:   PetscFunctionReturn(PETSC_SUCCESS);
611: }

613: /*@
614:   PetscDrawHGGetDraw - Gets the draw context associated with a histogram.

616:   Not Collective, draw is parallel if hist is parallel

618:   Input Parameter:
619: . hist - The histogram context

621:   Output Parameter:
622: . draw - The draw context

624:   Level: intermediate

626: .seealso: `PetscDraw`, `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`, `PetscDrawAxis`, `PetscDrawHGSetLimits()`
627: @*/
628: PetscErrorCode PetscDrawHGGetDraw(PetscDrawHG hist, PetscDraw *draw)
629: {
630:   PetscFunctionBegin;
632:   PetscAssertPointer(draw, 2);
633:   *draw = hist->win;
634:   PetscFunctionReturn(PETSC_SUCCESS);
635: }