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: /*@C
 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));

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

 71:   h->view    = NULL;
 72:   h->destroy = NULL;
 73:   h->color   = PETSC_DRAW_GREEN;
 74:   h->xmin    = PETSC_MAX_REAL;
 75:   h->xmax    = PETSC_MIN_REAL;
 76:   h->ymin    = 0.;
 77:   h->ymax    = 1.;
 78:   h->numBins = bins;
 79:   h->maxBins = bins;

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

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

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

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

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

 98:   Logically Collective

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

104:   Level: intermediate

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

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

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

126:   Logically Collective

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

131:   Level: intermediate

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

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

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

151:   Collective

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

156:   Level: intermediate

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

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

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

181:   Logically Collective

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

187:   Level: intermediate

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

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

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

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

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

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

239:   Collective

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

244:   Level: intermediate

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

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

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

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

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

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

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

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

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

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

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

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

384:   Collective

386:   Input Parameter:
387: . hg - The histogram context

389:   Level: intermediate

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

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

404:   Not Collective

406:   Input Parameters:
407: + hist   - The histogram context
408: - viewer - The viewer to view it with

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()`, `PetscDrawHGSetLimits()`
605: @*/
606: PetscErrorCode PetscDrawHGGetAxis(PetscDrawHG hist, PetscDrawAxis *axis)
607: {
608:   PetscFunctionBegin;
610:   PetscAssertPointer(axis, 2);
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;
634:   PetscAssertPointer(draw, 2);
635:   *draw = hist->win;
636:   PetscFunctionReturn(PETSC_SUCCESS);
637: }