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)((int)(xmax - xmin)) / numBins;
316:       while (initSize * numBins != (int)xmax - xmin) {
317:         initSize = PetscMax(initSize - 1, 1);
318:         numBins  = (int)((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;

414:   PetscFunctionBegin;

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

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

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

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

487: /*@
488:   PetscDrawHGSetColor - Sets the color the bars will be drawn with.

490:   Logically Collective

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

496:   Level: intermediate

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

505:   hist->color = color;
506:   PetscFunctionReturn(PETSC_SUCCESS);
507: }

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

514:   Logically Collective

516:   Input Parameters:
517: + hist  - The histogram context
518: . x_min - the horizontal lower limit
519: . x_max - the horizontal upper limit
520: . y_min - the vertical lower limit
521: - y_max - the vertical upper limit

523:   Level: intermediate

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

532:   hist->xmin = x_min;
533:   hist->xmax = x_max;
534:   hist->ymin = y_min;
535:   hist->ymax = y_max;
536:   PetscFunctionReturn(PETSC_SUCCESS);
537: }

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

542:   Not Collective

544:   Input Parameters:
545: + hist - The histogram context
546: - calc - Flag for calculation

548:   Level: intermediate

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

557:   hist->calcStats = calc;
558:   PetscFunctionReturn(PETSC_SUCCESS);
559: }

561: /*@
562:   PetscDrawHGIntegerBins - Turns on integer width bins

564:   Not Collective

566:   Input Parameters:
567: + hist - The histogram context
568: - ints - Flag for integer width bins

570:   Level: intermediate

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

579:   hist->integerBins = ints;
580:   PetscFunctionReturn(PETSC_SUCCESS);
581: }

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

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

591:   Input Parameter:
592: . hist - The histogram context

594:   Output Parameter:
595: . axis - The axis context

597:   Level: intermediate

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

610: /*@
611:   PetscDrawHGGetDraw - Gets the draw context associated with a histogram.

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

615:   Input Parameter:
616: . hist - The histogram context

618:   Output Parameter:
619: . draw - The draw context

621:   Level: intermediate

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