Date: 2025-03-28T21:11:10+00:00

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