Actual source code: hists.c


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

  9: PetscClassId PETSC_DRAWHG_CLASSID = 0;

 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: };

 30: #define CHUNKSIZE 100

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

 35:    Collective

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

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

 44:    Level: intermediate

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

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

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

 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: PetscErrorCode PetscDrawHGCreate(PetscDraw draw, int bins, PetscDrawHG *hist)
 59: {
 60:   PetscDrawHG h;

 62:   PetscFunctionBegin;

 67:   PetscCall(PetscHeaderCreate(h, PETSC_DRAWHG_CLASSID, "DrawHG", "Histogram", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawHGDestroy, NULL));

 69:   PetscCall(PetscObjectReference((PetscObject)draw));
 70:   h->win = draw;

 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;

 82:   PetscCall(PetscMalloc1(h->maxBins, &h->bins));

 84:   h->numValues   = 0;
 85:   h->maxValues   = CHUNKSIZE;
 86:   h->calcStats   = PETSC_FALSE;
 87:   h->integerBins = PETSC_FALSE;

 89:   PetscCall(PetscMalloc1(h->maxValues, &h->values));
 90:   PetscCall(PetscDrawAxisCreate(draw, &h->axis));

 92:   *hist = h;
 93:   PetscFunctionReturn(PETSC_SUCCESS);
 94: }

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

 99:    Logically Collective

101:    Input Parameters:
102: +  hist - The histogram context.
103: -  bins  - The number of bins.

105:    Level: intermediate

107: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGIntegerBins()`
108: @*/
109: PetscErrorCode PetscDrawHGSetNumberBins(PetscDrawHG hist, int bins)
110: {
111:   PetscFunctionBegin;

115:   if (hist->maxBins < bins) {
116:     PetscCall(PetscFree(hist->bins));
117:     PetscCall(PetscMalloc1(bins, &hist->bins));
118:     hist->maxBins = bins;
119:   }
120:   hist->numBins = bins;
121:   PetscFunctionReturn(PETSC_SUCCESS);
122: }

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

127:   Logically Collective

129:   Input Parameter:
130: . hist - The histogram context.

132:   Level: intermediate

134: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`
135: @*/
136: PetscErrorCode PetscDrawHGReset(PetscDrawHG hist)
137: {
138:   PetscFunctionBegin;

141:   hist->xmin      = PETSC_MAX_REAL;
142:   hist->xmax      = PETSC_MIN_REAL;
143:   hist->ymin      = 0.0;
144:   hist->ymax      = 1.0;
145:   hist->numValues = 0;
146:   PetscFunctionReturn(PETSC_SUCCESS);
147: }

149: /*@C
150:   PetscDrawHGDestroy - Frees all space taken up by histogram data structure.

152:   Collective

154:   Input Parameter:
155: . hist - The histogram context

157:   Level: intermediate

159: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`
160: @*/
161: PetscErrorCode PetscDrawHGDestroy(PetscDrawHG *hist)
162: {
163:   PetscFunctionBegin;
164:   if (!*hist) PetscFunctionReturn(PETSC_SUCCESS);
166:   if (--((PetscObject)(*hist))->refct > 0) {
167:     *hist = NULL;
168:     PetscFunctionReturn(PETSC_SUCCESS);
169:   }

171:   PetscCall(PetscFree((*hist)->bins));
172:   PetscCall(PetscFree((*hist)->values));
173:   PetscCall(PetscDrawAxisDestroy(&(*hist)->axis));
174:   PetscCall(PetscDrawDestroy(&(*hist)->win));
175:   PetscCall(PetscHeaderDestroy(hist));
176:   PetscFunctionReturn(PETSC_SUCCESS);
177: }

179: /*@
180:   PetscDrawHGAddValue - Adds another value to the histogram.

182:   Logically Collective

184:   Input Parameters:
185: + hist  - The histogram
186: - value - The value

188:   Level: intermediate

190: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`, `PetscDrawHGReset()`
191: @*/
192: PetscErrorCode PetscDrawHGAddValue(PetscDrawHG hist, PetscReal value)
193: {
194:   PetscFunctionBegin;

197:   /* Allocate more memory if necessary */
198:   if (hist->numValues >= hist->maxValues) {
199:     PetscReal *tmp;

201:     PetscCall(PetscMalloc1(hist->maxValues + CHUNKSIZE, &tmp));
202:     PetscCall(PetscArraycpy(tmp, hist->values, hist->maxValues));
203:     PetscCall(PetscFree(hist->values));

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

233:   hist->values[hist->numValues++] = value;
234:   PetscFunctionReturn(PETSC_SUCCESS);
235: }

237: /*@
238:   PetscDrawHGDraw - Redraws a histogram.

240:   Collective

242:   Input Parameter:
243: . hist - The histogram context

245:   Level: intermediate

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

259:   PetscFunctionBegin;
261:   PetscCall(PetscDrawIsNull(hist->win, &isnull));
262:   if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
263:   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)hist), &rank));

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

268:   color = hist->color;
269:   if (color == PETSC_DRAW_ROTATE) bcolor = PETSC_DRAW_BLACK + 1;
270:   else bcolor = color;

272:   xmin      = hist->xmin;
273:   xmax      = hist->xmax;
274:   ymin      = hist->ymin;
275:   ymax      = hist->ymax;
276:   numValues = hist->numValues;
277:   values    = hist->values;
278:   mean      = 0.0;
279:   var       = 0.0;

281:   draw = hist->win;
282:   PetscCall(PetscDrawCheckResizedWindow(draw));
283:   PetscCall(PetscDrawClear(draw));

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

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

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

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

377:   PetscCall(PetscDrawFlush(draw));
378:   PetscCall(PetscDrawPause(draw));
379:   PetscFunctionReturn(PETSC_SUCCESS);
380: }

382: /*@
383:   PetscDrawHGSave - Saves a drawn image

385:   Collective

387:   Input Parameter:
388: . hist - The histogram context

390:   Level: intermediate

392: .seealso: `PetscDrawSave()`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`
393: @*/
394: PetscErrorCode PetscDrawHGSave(PetscDrawHG hg)
395: {
396:   PetscFunctionBegin;
398:   PetscCall(PetscDrawSave(hg->win));
399:   PetscFunctionReturn(PETSC_SUCCESS);
400: }

402: /*@
403:   PetscDrawHGView - Prints the histogram information to a viewer

405:   Not Collective

407:   Input Parameter:
408: . hist - The histogram context

410:   Level: beginner

412: .seealso: `PetscDrawHG`, `PetscViewer`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`
413: @*/
414: PetscErrorCode PetscDrawHGView(PetscDrawHG hist, PetscViewer viewer)
415: {
416:   PetscReal xmax, xmin, *bins, *values, binSize, binLeft, binRight, mean, var;
417:   PetscInt  numBins, numBinsOld, numValues, initSize, i, p;

419:   PetscFunctionBegin;

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

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

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

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

492: /*@
493:   PetscDrawHGSetColor - Sets the color the bars will be drawn with.

495:   Logically Collective

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

501:   Level: intermediate

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

510:   hist->color = color;
511:   PetscFunctionReturn(PETSC_SUCCESS);
512: }

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

519:   Logically Collective

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

528:   Level: intermediate

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

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

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

547:   Not Collective

549:   Input Parameters:
550: + hist - The histogram context
551: - calc - Flag for calculation

553:   Level: intermediate

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

562:   hist->calcStats = calc;
563:   PetscFunctionReturn(PETSC_SUCCESS);
564: }

566: /*@
567:   PetscDrawHGIntegerBins - Turns on integer width bins

569:   Not Collective

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

575:   Level: intermediate

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

584:   hist->integerBins = ints;
585:   PetscFunctionReturn(PETSC_SUCCESS);
586: }

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

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

596:   Input Parameter:
597: . hist - The histogram context

599:   Output Parameter:
600: . axis - The axis context

602:   Level: intermediate

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

615: /*@C
616:   PetscDrawHGGetDraw - Gets the draw context associated with a histogram.

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

620:   Input Parameter:
621: . hist - The histogram context

623:   Output Parameter:
624: . draw  - The draw context

626:   Level: intermediate

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