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 on PetscDraw

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

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

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

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

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

     52:    Level: intermediate

     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()

     58: @*/
     59: PetscErrorCode  PetscDrawHGCreate(PetscDraw draw,int bins,PetscDrawHG *hist)
     60: {
     61:   PetscDrawHG    h;

     69:   PetscHeaderCreate(h,PETSC_DRAWHG_CLASSID,"DrawHG","Histogram","Draw",PetscObjectComm((PetscObject)draw),PetscDrawHGDestroy,NULL);
     70:   PetscLogObjectParent((PetscObject)draw,(PetscObject)h);

     72:   PetscObjectReference((PetscObject)draw);
     73:   h->win = draw;

     75:   h->view        = NULL;
     76:   h->destroy     = NULL;
     77:   h->color       = PETSC_DRAW_GREEN;
     78:   h->xmin        = PETSC_MAX_REAL;
     79:   h->xmax        = PETSC_MIN_REAL;
     80:   h->ymin        = 0.;
     81:   h->ymax        = 1.;
     82:   h->numBins     = bins;
     83:   h->maxBins     = bins;

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

     87:   h->numValues   = 0;
     88:   h->maxValues   = CHUNKSIZE;
     89:   h->calcStats   = PETSC_FALSE;
     90:   h->integerBins = PETSC_FALSE;

     92:   PetscMalloc1(h->maxValues,&h->values);
     93:   PetscLogObjectMemory((PetscObject)h,(h->maxBins + h->maxValues)*sizeof(PetscReal));

     95:   PetscDrawAxisCreate(draw,&h->axis);
     96:   PetscLogObjectParent((PetscObject)h,(PetscObject)h->axis);

     98:   *hist = h;
     99:   return(0);
    100: }

    102: /*@
    103:    PetscDrawHGSetNumberBins - Change the number of bins that are to be drawn.

    105:    Logically Collective on PetscDrawHG

    107:    Input Parameter:
    108: +  hist - The histogram context.
    109: -  bins  - The number of bins.

    111:    Level: intermediate

    113: .seealso: PetscDrawHGCreate(), PetscDrawHG, PetscDrawHGDraw(), PetscDrawHGIntegerBins()

    115: @*/
    116: PetscErrorCode  PetscDrawHGSetNumberBins(PetscDrawHG hist, int bins)
    117: {

    124:   if (hist->maxBins < bins) {
    125:     PetscFree(hist->bins);
    126:     PetscMalloc1(bins, &hist->bins);
    127:     PetscLogObjectMemory((PetscObject)hist, (bins - hist->maxBins) * sizeof(PetscReal));
    128:     hist->maxBins = bins;
    129:   }
    130:   hist->numBins = bins;
    131:   return(0);
    132: }

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

    137:   Logically Collective on PetscDrawHG

    139:   Input Parameter:
    140: . hist - The histogram context.

    142:   Level: intermediate

    144: .seealso: PetscDrawHGCreate(), PetscDrawHG, PetscDrawHGDraw(), PetscDrawHGAddValue()

    146: @*/
    147: PetscErrorCode  PetscDrawHGReset(PetscDrawHG hist)
    148: {

    152:   hist->xmin      = PETSC_MAX_REAL;
    153:   hist->xmax      = PETSC_MIN_REAL;
    154:   hist->ymin      = 0.0;
    155:   hist->ymax      = 0.0;
    156:   hist->numValues = 0;
    157:   return(0);
    158: }

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

    163:   Collective on PetscDrawHG

    165:   Input Parameter:
    166: . hist - The histogram context

    168:   Level: intermediate

    170: .seealso:  PetscDrawHGCreate(), PetscDrawHG
    171: @*/
    172: PetscErrorCode  PetscDrawHGDestroy(PetscDrawHG *hist)
    173: {

    177:   if (!*hist) return(0);
    179:   if (--((PetscObject)(*hist))->refct > 0) {*hist = NULL; return(0);}

    181:   PetscFree((*hist)->bins);
    182:   PetscFree((*hist)->values);
    183:   PetscDrawAxisDestroy(&(*hist)->axis);
    184:   PetscDrawDestroy(&(*hist)->win);
    185:   PetscHeaderDestroy(hist);
    186:   return(0);
    187: }

    189: /*@
    190:   PetscDrawHGAddValue - Adds another value to the histogram.

    192:   Logically Collective on PetscDrawHG

    194:   Input Parameters:
    195: + hist  - The histogram
    196: - value - The value

    198:   Level: intermediate

    200: .seealso: PetscDrawHGCreate(), PetscDrawHG, PetscDrawHGDraw(), PetscDrawHGAddValue(), PetscDrawHGReset()
    201: @*/
    202: PetscErrorCode  PetscDrawHGAddValue(PetscDrawHG hist, PetscReal value)
    203: {

    207:   /* Allocate more memory if necessary */
    208:   if (hist->numValues >= hist->maxValues) {
    209:     PetscReal      *tmp;

    212:     PetscMalloc1(hist->maxValues+CHUNKSIZE, &tmp);
    213:     PetscLogObjectMemory((PetscObject)hist, CHUNKSIZE * sizeof(PetscReal));
    214:     PetscArraycpy(tmp, hist->values, hist->maxValues);
    215:     PetscFree(hist->values);

    217:     hist->values     = tmp;
    218:     hist->maxValues += CHUNKSIZE;
    219:   }
    220:   /* I disagree with the original Petsc implementation here. There should be no overshoot, but rather the
    221:      stated convention of using half-open intervals (always the way to go) */
    222:   if (!hist->numValues) {
    223:     hist->xmin = value;
    224:     hist->xmax = value;
    225: #if 1
    226:   } else {
    227:     /* Update limits */
    228:     if (value > hist->xmax) hist->xmax = value;
    229:     if (value < hist->xmin) hist->xmin = value;
    230: #else
    231:   } else if (hist->numValues == 1) {
    232:     /* Update limits -- We need to overshoot the largest value somewhat */
    233:     if (value > hist->xmax) hist->xmax = value + 0.001*(value - hist->xmin)/hist->numBins;
    234:     if (value < hist->xmin) {
    235:       hist->xmin = value;
    236:       hist->xmax = hist->xmax + 0.001*(hist->xmax - hist->xmin)/hist->numBins;
    237:     }
    238:   } else {
    239:     /* Update limits -- We need to overshoot the largest value somewhat */
    240:     if (value > hist->xmax) hist->xmax = value + 0.001*(hist->xmax - hist->xmin)/hist->numBins;
    241:     if (value < hist->xmin) hist->xmin = value;
    242: #endif
    243:   }

    245:   hist->values[hist->numValues++] = value;
    246:   return(0);
    247: }

    249: /*@
    250:   PetscDrawHGDraw - Redraws a histogram.

    252:   Collective on PetscDrawHG

    254:   Input Parameter:
    255: . hist - The histogram context

    257:   Level: intermediate

    259: .seealso: PetscDrawHGCreate(), PetscDrawHG, PetscDrawHGDraw(), PetscDrawHGAddValue(), PetscDrawHGReset()

    261: @*/
    262: PetscErrorCode  PetscDrawHGDraw(PetscDrawHG hist)
    263: {
    264:   PetscDraw      draw;
    265:   PetscBool      isnull;
    266:   PetscReal      xmin,xmax,ymin,ymax,*bins,*values,binSize,binLeft,binRight,maxHeight,mean,var;
    267:   char           title[256];
    268:   char           xlabel[256];
    269:   PetscInt       numBins,numBinsOld,numValues,initSize,i,p,bcolor,color;
    270:   PetscMPIInt    rank;

    275:   PetscDrawIsNull(hist->win,&isnull);
    276:   if (isnull) return(0);
    277:   MPI_Comm_rank(PetscObjectComm((PetscObject)hist),&rank);

    279:   if ((hist->xmin >= hist->xmax) || (hist->ymin >= hist->ymax)) return(0);
    280:   if (hist->numValues < 1) return(0);

    282:   color = hist->color;
    283:   if (color == PETSC_DRAW_ROTATE) bcolor = PETSC_DRAW_BLACK+1;
    284:   else bcolor = color;

    286:   xmin      = hist->xmin;
    287:   xmax      = hist->xmax;
    288:   ymin      = hist->ymin;
    289:   ymax      = hist->ymax;
    290:   numValues = hist->numValues;
    291:   values    = hist->values;
    292:   mean      = 0.0;
    293:   var       = 0.0;

    295:   draw = hist->win;
    296:   PetscDrawCheckResizedWindow(draw);
    297:   PetscDrawClear(draw);

    299:   if (xmin == xmax) {
    300:     /* Calculate number of points in each bin */
    301:     bins    = hist->bins;
    302:     bins[0] = 0.;
    303:     for (p = 0; p < numValues; p++) {
    304:       if (values[p] == xmin) bins[0]++;
    305:       mean += values[p];
    306:       var  += values[p]*values[p];
    307:     }
    308:     maxHeight = bins[0];
    309:     if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
    310:     xmax = xmin + 1;
    311:     PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax);
    312:     if (hist->calcStats) {
    313:       mean /= numValues;
    314:       if (numValues > 1) var = (var - numValues*mean*mean) / (numValues-1);
    315:       else var = 0.0;
    316:       PetscSNPrintf(title, 256, "Mean: %g  Var: %g", (double)mean, (double)var);
    317:       PetscSNPrintf(xlabel,256, "Total: %D", numValues);
    318:       PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL);
    319:     }
    320:     PetscDrawAxisDraw(hist->axis);
    321:     PetscDrawCollectiveBegin(draw);
    322:     if (!rank) { /* Draw bins */
    323:       binLeft  = xmin;
    324:       binRight = xmax;
    325:       PetscDrawRectangle(draw,binLeft,ymin,binRight,bins[0],bcolor,bcolor,bcolor,bcolor);
    326:       PetscDrawLine(draw,binLeft,ymin,binLeft,bins[0],PETSC_DRAW_BLACK);
    327:       PetscDrawLine(draw,binRight,ymin,binRight,bins[0],PETSC_DRAW_BLACK);
    328:       PetscDrawLine(draw,binLeft,bins[0],binRight,bins[0],PETSC_DRAW_BLACK);
    329:     }
    330:     PetscDrawCollectiveEnd(draw);
    331:   } else {
    332:     numBins    = hist->numBins;
    333:     numBinsOld = hist->numBins;
    334:     if (hist->integerBins && (((int) xmax - xmin) + 1.0e-05 > xmax - xmin)) {
    335:       initSize = (int) ((int) xmax - xmin)/numBins;
    336:       while (initSize*numBins != (int) xmax - xmin) {
    337:         initSize = PetscMax(initSize - 1, 1);
    338:         numBins  = (int) ((int) xmax - xmin)/initSize;
    339:         PetscDrawHGSetNumberBins(hist, numBins);
    340:       }
    341:     }
    342:     binSize = (xmax - xmin)/numBins;
    343:     bins    = hist->bins;

    345:     PetscArrayzero(bins, numBins);

    347:     maxHeight = 0.0;
    348:     for (i = 0; i < numBins; i++) {
    349:       binLeft  = xmin + binSize*i;
    350:       binRight = xmin + binSize*(i+1);
    351:       for (p = 0; p < numValues; p++) {
    352:         if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
    353:         /* Handle last bin separately */
    354:         if ((i == numBins-1) && (values[p] == binRight)) bins[i]++;
    355:         if (!i) {
    356:           mean += values[p];
    357:           var  += values[p]*values[p];
    358:         }
    359:       }
    360:       maxHeight = PetscMax(maxHeight, bins[i]);
    361:     }
    362:     if (maxHeight > ymax) ymax = hist->ymax = maxHeight;

    364:     PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax);
    365:     if (hist->calcStats) {
    366:       mean /= numValues;
    367:       if (numValues > 1) var = (var - numValues*mean*mean) / (numValues-1);
    368:       else var = 0.0;
    369:       PetscSNPrintf(title, 256,"Mean: %g  Var: %g", (double)mean, (double)var);
    370:       PetscSNPrintf(xlabel,256, "Total: %D", numValues);
    371:       PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL);
    372:     }
    373:     PetscDrawAxisDraw(hist->axis);
    374:     PetscDrawCollectiveBegin(draw);
    375:     if (!rank) { /* Draw bins */
    376:       for (i = 0; i < numBins; i++) {
    377:         binLeft  = xmin + binSize*i;
    378:         binRight = xmin + binSize*(i+1);
    379:         PetscDrawRectangle(draw,binLeft,ymin,binRight,bins[i],bcolor,bcolor,bcolor,bcolor);
    380:         PetscDrawLine(draw,binLeft,ymin,binLeft,bins[i],PETSC_DRAW_BLACK);
    381:         PetscDrawLine(draw,binRight,ymin,binRight,bins[i],PETSC_DRAW_BLACK);
    382:         PetscDrawLine(draw,binLeft,bins[i],binRight,bins[i],PETSC_DRAW_BLACK);
    383:         if (color == PETSC_DRAW_ROTATE && bins[i]) bcolor++;
    384:         if (bcolor > PETSC_DRAW_BASIC_COLORS-1) bcolor = PETSC_DRAW_BLACK+1;
    385:       }
    386:     }
    387:     PetscDrawCollectiveEnd(draw);
    388:     PetscDrawHGSetNumberBins(hist,numBinsOld);
    389:   }

    391:   PetscDrawFlush(draw);
    392:   PetscDrawPause(draw);
    393:   return(0);
    394: }

    396: /*@
    397:   PetscDrawHGSave - Saves a drawn image

    399:   Collective on PetscDrawHG

    401:   Input Parameter:
    402: . hist - The histogram context

    404:   Level: intermediate

    406: .seealso:  PetscDrawHGCreate(), PetscDrawHGGetDraw(), PetscDrawSetSave(), PetscDrawSave(), PetscDrawHGDraw()
    407: @*/
    408: PetscErrorCode  PetscDrawHGSave(PetscDrawHG hg)
    409: {

    414:   PetscDrawSave(hg->win);
    415:   return(0);
    416: }

    418: /*@
    419:   PetscDrawHGView - Prints the histogram information.

    421:   Not collective

    423:   Input Parameter:
    424: . hist - The histogram context

    426:   Level: beginner

    428: .seealso:  PetscDrawHGCreate(), PetscDrawHGGetDraw(), PetscDrawSetSave(), PetscDrawSave(), PetscDrawHGDraw()

    430: @*/
    431: PetscErrorCode  PetscDrawHGView(PetscDrawHG hist,PetscViewer viewer)
    432: {
    433:   PetscReal      xmax,xmin,*bins,*values,binSize,binLeft,binRight,mean,var;
    435:   PetscInt       numBins,numBinsOld,numValues,initSize,i,p;

    440:   if ((hist->xmin > hist->xmax) || (hist->ymin >= hist->ymax)) return(0);
    441:   if (hist->numValues < 1) return(0);

    443:   if (!viewer){
    444:     PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)hist),&viewer);
    445:   }
    446:   PetscObjectPrintClassNamePrefixType((PetscObject)hist,viewer);
    447:   xmax      = hist->xmax;
    448:   xmin      = hist->xmin;
    449:   numValues = hist->numValues;
    450:   values    = hist->values;
    451:   mean      = 0.0;
    452:   var       = 0.0;
    453:   if (xmax == xmin) {
    454:     /* Calculate number of points in the bin */
    455:     bins    = hist->bins;
    456:     bins[0] = 0.;
    457:     for (p = 0; p < numValues; p++) {
    458:       if (values[p] == xmin) bins[0]++;
    459:       mean += values[p];
    460:       var  += values[p]*values[p];
    461:     }
    462:     /* Draw bins */
    463:     PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", 0, (double)xmin, (double)xmax, (double)bins[0]);
    464:   } else {
    465:     numBins    = hist->numBins;
    466:     numBinsOld = hist->numBins;
    467:     if (hist->integerBins && (((int) xmax - xmin) + 1.0e-05 > xmax - xmin)) {
    468:       initSize = (int) ((int) xmax - xmin)/numBins;
    469:       while (initSize*numBins != (int) xmax - xmin) {
    470:         initSize = PetscMax(initSize - 1, 1);
    471:         numBins  = (int) ((int) xmax - xmin)/initSize;
    472:         PetscDrawHGSetNumberBins(hist, numBins);
    473:       }
    474:     }
    475:     binSize = (xmax - xmin)/numBins;
    476:     bins    = hist->bins;

    478:     /* Calculate number of points in each bin */
    479:     PetscArrayzero(bins, numBins);
    480:     for (i = 0; i < numBins; i++) {
    481:       binLeft  = xmin + binSize*i;
    482:       binRight = xmin + binSize*(i+1);
    483:       for (p = 0; p < numValues; p++) {
    484:         if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
    485:         /* Handle last bin separately */
    486:         if ((i == numBins-1) && (values[p] == binRight)) bins[i]++;
    487:         if (!i) {
    488:           mean += values[p];
    489:           var  += values[p]*values[p];
    490:         }
    491:       }
    492:     }
    493:     /* Draw bins */
    494:     for (i = 0; i < numBins; i++) {
    495:       binLeft  = xmin + binSize*i;
    496:       binRight = xmin + binSize*(i+1);
    497:       PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", (int)i, (double)binLeft, (double)binRight, (double)bins[i]);
    498:     }
    499:     PetscDrawHGSetNumberBins(hist, numBinsOld);
    500:   }

    502:   if (hist->calcStats) {
    503:     mean /= numValues;
    504:     if (numValues > 1) var = (var - numValues*mean*mean) / (numValues-1);
    505:     else var = 0.0;
    506:     PetscViewerASCIIPrintf(viewer, "Mean: %g  Var: %g\n", (double)mean, (double)var);
    507:     PetscViewerASCIIPrintf(viewer, "Total: %D\n", numValues);
    508:   }
    509:   return(0);
    510: }

    512: /*@
    513:   PetscDrawHGSetColor - Sets the color the bars will be drawn with.

    515:   Logically Collective on PetscDrawHG

    517:   Input Parameters:
    518: + hist - The histogram context
    519: - color - one of the colors defined in petscdraw.h or PETSC_DRAW_ROTATE to make each bar a
    520:           different color

    522:   Level: intermediate

    524: .seealso:  PetscDrawHGCreate(), PetscDrawHGGetDraw(), PetscDrawSetSave(), PetscDrawSave(), PetscDrawHGDraw(), PetscDrawHGGetAxis()

    526: @*/
    527: PetscErrorCode  PetscDrawHGSetColor(PetscDrawHG hist,int color)
    528: {

    532:   hist->color = color;
    533:   return(0);
    534: }

    536: /*@
    537:   PetscDrawHGSetLimits - Sets the axis limits for a histogram. If more
    538:   points are added after this call, the limits will be adjusted to
    539:   include those additional points.

    541:   Logically Collective on PetscDrawHG

    543:   Input Parameters:
    544: + hist - The histogram context
    545: - x_min,x_max,y_min,y_max - The limits

    547:   Level: intermediate

    549: .seealso:  PetscDrawHGCreate(), PetscDrawHGGetDraw(), PetscDrawSetSave(), PetscDrawSave(), PetscDrawHGDraw(), PetscDrawHGGetAxis()

    551: @*/
    552: PetscErrorCode  PetscDrawHGSetLimits(PetscDrawHG hist, PetscReal x_min, PetscReal x_max, int y_min, int y_max)
    553: {

    557:   hist->xmin = x_min;
    558:   hist->xmax = x_max;
    559:   hist->ymin = y_min;
    560:   hist->ymax = y_max;
    561:   return(0);
    562: }

    564: /*@
    565:   PetscDrawHGCalcStats - Turns on calculation of descriptive statistics

    567:   Not collective

    569:   Input Parameters:
    570: + hist - The histogram context
    571: - calc - Flag for calculation

    573:   Level: intermediate

    575: .seealso:  PetscDrawHGCreate(), PetscDrawHGAddValue(), PetscDrawHGView(), PetscDrawHGDraw()

    577: @*/
    578: PetscErrorCode  PetscDrawHGCalcStats(PetscDrawHG hist, PetscBool calc)
    579: {

    583:   hist->calcStats = calc;
    584:   return(0);
    585: }

    587: /*@
    588:   PetscDrawHGIntegerBins - Turns on integer width bins

    590:   Not collective

    592:   Input Parameters:
    593: + hist - The histogram context
    594: - ints - Flag for integer width bins

    596:   Level: intermediate

    598: .seealso:  PetscDrawHGCreate(), PetscDrawHGAddValue(), PetscDrawHGView(), PetscDrawHGDraw(), PetscDrawHGSetColor()

    600: @*/
    601: PetscErrorCode  PetscDrawHGIntegerBins(PetscDrawHG hist, PetscBool ints)
    602: {

    606:   hist->integerBins = ints;
    607:   return(0);
    608: }

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

    616:   Not Collective, PetscDrawAxis is parallel if PetscDrawHG is parallel

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

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

    624:   Level: intermediate

    626: .seealso:  PetscDrawHGCreate(), PetscDrawHGAddValue(), PetscDrawHGView(), PetscDrawHGDraw(), PetscDrawHGSetColor(), PetscDrawAxis, PetscDrawHGSetLimits()

    628: @*/
    629: PetscErrorCode  PetscDrawHGGetAxis(PetscDrawHG hist,PetscDrawAxis *axis)
    630: {
    634:   *axis = hist->axis;
    635:   return(0);
    636: }

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

    641:   Not Collective, PetscDraw is parallel if PetscDrawHG is parallel

    643:   Input Parameter:
    644: . hist - The histogram context

    646:   Output Parameter:
    647: . draw  - The draw context

    649:   Level: intermediate

    651: .seealso:  PetscDrawHGCreate(), PetscDrawHGAddValue(), PetscDrawHGView(), PetscDrawHGDraw(), PetscDrawHGSetColor(), PetscDrawAxis, PetscDrawHGSetLimits()

    653: @*/
    654: PetscErrorCode  PetscDrawHGGetDraw(PetscDrawHG hist,PetscDraw *draw)
    655: {
    659:   *draw = hist->win;
    660:   return(0);
    661: }