Date: 2015-10-02T21:59:18+00:00

Actual source code: bars.c
petsc-3.6.2 2015-10-02
Report Typos and Errors

      2: /*
      3:   Contains the data structure for plotting a bargraph in a window with an axis.
      4: */
      5: #include <petscdraw.h>         /*I "petscdraw.h" I*/
      6: #include <petsc/private/petscimpl.h>         /*I "petscsys.h" I*/
      7: #include <petscviewer.h>         /*I "petscviewer.h" I*/
      8: #include <../src/sys/classes/draw/utils/axisimpl.h>   /* so we can directly modify axis xticks */

     10: PetscClassId PETSC_DRAWBAR_CLASSID = 0;

     12: struct _p_PetscDrawBar {
     13:   PETSCHEADER(int);
     14:   PetscErrorCode (*destroy)(PetscDrawSP);
     15:   PetscErrorCode (*view)(PetscDrawSP,PetscViewer);
     16:   PetscDraw      win;
     17:   PetscDrawAxis  axis;
     18:   PetscReal      ymin,ymax;
     19:   int            numBins;
     20:   PetscReal      *values;
     21:   int            color;
     22:   char           **labels;
     23:   PetscBool      sort;
     24:   PetscReal      sorttolerance;
     25: };

     27: #define CHUNKSIZE 100

     31: /*@C
     32:    PetscDrawBarCreate - Creates a bar graph data structure.

     34:    Collective over PetscDraw

     36:    Input Parameters:
     37: .  draw  - The window where the graph will be made

     39:    Output Parameters:
     40: .  bar - The bar graph context

     42:    Level: intermediate

     44:    Concepts: bar graph^creating

     46: .seealso: PetscDrawBarDestroy()

     48: @*/
     49: PetscErrorCode  PetscDrawBarCreate(PetscDraw draw, PetscDrawBar *bar)
     50: {
     51:   PetscDrawBar    h;
     52:   PetscBool      isnull;

     58:   PetscHeaderCreate(h, PETSC_DRAWBAR_CLASSID, "PetscDrawBar", "Bar Graph", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawBarDestroy, NULL);

     60:   h->view        = NULL;
     61:   h->destroy     = NULL;
     62:   h->win         = draw;

     64:   PetscObjectReference((PetscObject) draw);

     66:   h->color       = PETSC_DRAW_GREEN;
     67:   h->ymin        = 0.;  /* if user has not set these then they are determined from the data */
     68:   h->ymax        = 0.;
     69:   h->numBins     = 0;

     71:   PetscObjectTypeCompare((PetscObject) draw, PETSC_DRAW_NULL, &isnull);
     72:   if (!isnull) {
     73:     PetscDrawAxisCreate(draw, &h->axis);
     74:     h->axis->xticks = NULL;
     75:   } else h->axis = NULL;
     76:   *bar = h;
     77:   return(0);
     78: }

     82: /*@C
     83:    PetscDrawBarSetData

     85:    Not Collective (ignored except on processor 0 of PetscDrawBar)

     87:    Input Parameter:
     88: +  bar - The bar graph context.
     89: .  bins  - number of items
     90: .  values - values of each item
     91: -  labels - optional label for each bar, NULL terminated array of strings

     93:    Level: intermediate

     96: @*/
     97: PetscErrorCode  PetscDrawBarSetData(PetscDrawBar bar, PetscInt bins,const PetscReal data[],const char *const *labels)
     98: {

    103:   if (bar->numBins != bins) {
    104:     PetscFree(bar->values);
    105:     PetscMalloc1(bins, &bar->values);
    106:     bar->numBins = bins;
    107:   }
    108:   PetscMemcpy(bar->values,data,bins*sizeof(PetscReal));
    109:   bar->numBins = bins;
    110:   if (labels) {
    111:     PetscStrArrayallocpy(labels,&bar->labels);
    112:   }
    113:   return(0);
    114: }

    118: /*@C
    119:   PetscDrawBarDestroy - Frees all space taken up by bar graph data structure.

    121:   Collective over PetscDrawBar

    123:   Input Parameter:
    124: . bar - The bar graph context

    126:   Level: intermediate

    128: .seealso:  PetscDrawBarCreate()
    129: @*/
    130: PetscErrorCode  PetscDrawBarDestroy(PetscDrawBar *bar)
    131: {

    135:   if (!*bar) return(0);

    138:   if (--((PetscObject)(*bar))->refct > 0) return(0);
    139:   PetscDrawAxisDestroy(&(*bar)->axis);
    140:   PetscDrawDestroy(&(*bar)->win);
    141:   PetscFree((*bar)->values);
    142:   PetscStrArrayDestroy(&(*bar)->labels);
    143:   PetscHeaderDestroy(bar);
    144:   return(0);
    145: }

    149: /*@
    150:   PetscDrawBarDraw - Redraws a bar graph.

    152:   Not Collective (ignored except on processor 0 of PetscDrawBar)

    154:   Input Parameter:
    155: . bar - The bar graph context

    157:   Level: intermediate

    159: @*/
    160: PetscErrorCode  PetscDrawBarDraw(PetscDrawBar bar)
    161: {
    162:   PetscDraw      draw = bar->win;
    163:   PetscBool      isnull;
    164:   PetscReal      xmin,xmax,ymin,ymax,*values,binLeft,binRight;
    165:   PetscInt       numValues,i,bcolor,color,idx,*perm,nplot;
    167:   char           **labels;

    171:   PetscObjectTypeCompare((PetscObject) draw, PETSC_DRAW_NULL, &isnull);
    172:   if (isnull) return(0);
    173:   if (bar->numBins < 1) return(0);

    175:   color = bar->color;
    176:   if (color == PETSC_DRAW_ROTATE) bcolor = 2;
    177:   else bcolor = color;

    179:   numValues = bar->numBins;
    180:   values    = bar->values;
    181:   if (bar->ymin == bar->ymax) {
    182:     /* user has not set bounds on bars so set them based on the data */
    183:     ymin = PETSC_MAX_REAL;
    184:     ymax = PETSC_MIN_REAL;
    185:     for (i=0; i<numValues; i++) {
    186:       ymin = PetscMin(ymin,values[i]);
    187:       ymax = PetscMax(ymax,values[i]);
    188:     }
    189:   } else {
    190:     ymin      = bar->ymin;
    191:     ymax      = bar->ymax;
    192:   }
    193:   nplot  = numValues;  /* number of points to actually plot; if some are lower than requested tolerance */
    194:   xmin   = 0.0;
    195:   labels = bar->labels;

    197:   if (bar->sort) {
    198:     PetscMalloc1(numValues,&perm);
    199:     for (i=0; i<numValues;i++) perm[i] = i;
    200:     PetscSortRealWithPermutation(numValues,values,perm);
    201:     if (bar->sorttolerance) {
    202:       for (i=0; i<numValues;i++) {
    203:         if (values[perm[numValues - i - 1]] < bar->sorttolerance) {
    204:           nplot = i;
    205:           break;
    206:         }
    207:       }
    208:     }
    209:   }

    211:   xmax   = nplot;
    212:   PetscDrawAxisSetLimits(bar->axis, xmin, xmax, ymin, ymax);
    213:   PetscDrawClear(draw);
    214:   PetscDrawAxisDraw(bar->axis);

    216:   /* Draw bins */
    217:   for (i = 0; i < nplot; i++) {
    218:     idx = (bar->sort ? perm[numValues - i - 1] : i);
    219:     binLeft  = xmin + i;
    220:     binRight = xmin + i + 1;
    221:     PetscDrawRectangle(draw,binLeft,ymin,binRight,values[idx],bcolor,bcolor,bcolor,bcolor);
    222:     PetscDrawLine(draw,binLeft,ymin,binLeft,values[idx],PETSC_DRAW_BLACK);
    223:     PetscDrawLine(draw,binRight,ymin,binRight,values[idx],PETSC_DRAW_BLACK);
    224:     PetscDrawLine(draw,binLeft,values[idx],binRight,values[idx],PETSC_DRAW_BLACK);
    225:     if (labels) {
    226:       PetscReal h;
    227:       PetscDrawStringGetSize(draw,NULL,&h);
    228:       PetscDrawStringCentered(draw,.5*(binLeft+binRight),ymin - 1.2*h,bcolor,labels[idx]);
    229:     }
    230:     if (color == PETSC_DRAW_ROTATE) bcolor++;
    231:     if (bcolor > 31) bcolor = 2;
    232:   }
    233:   if (bar->sort) {
    234:     PetscFree(perm);
    235:   }
    236:   PetscDrawSynchronizedFlush(draw);
    237:   PetscDrawPause(draw);
    238:   return(0);
    239: }

    243: /*@
    244:   PetscDrawBarSetColor - Sets the color the bars will be drawn with.

    246:   Not Collective (ignored except on processor 0 of PetscDrawBar)

    248:   Input Parameters:
    249: + bar - The bar graph context
    250: - color - one of the colors defined in petscdraw.h or PETSC_DRAW_ROTATE to make each bar a
    251:           different color

    253:   Level: intermediate

    255: @*/
    256: PetscErrorCode  PetscDrawBarSetColor(PetscDrawBar bar, int color)
    257: {
    260:   bar->color = color;
    261:   return(0);
    262: }

    266: /*@
    267:   PetscDrawBarSort - Sorts the values before drawing the bar chart

    269:   Not Collective (ignored except on processor 0 of PetscDrawBar)

    271:   Input Parameters:
    272: + bar - The bar graph context
    273: . sort - PETSC_TRUE to sort the values
    274: . tolerance - discard values less than tolerance

    276:   Level: intermediate

    278:   Concepts: bar graph^setting axis
    279: @*/
    280: PetscErrorCode  PetscDrawBarSort(PetscDrawBar bar, PetscBool sort, PetscReal tolerance)
    281: {
    284:   bar->sort          = sort;
    285:   bar->sorttolerance = tolerance;
    286:   return(0);
    287: }

    291: /*@
    292:   PetscDrawBarSetLimits - Sets the axis limits for a bar graph. If more
    293:   points are added after this call, the limits will be adjusted to
    294:   include those additional points.

    296:   Not Collective (ignored except on processor 0 of PetscDrawBar)

    298:   Input Parameters:
    299: + bar - The bar graph context
    300: - y_min,y_max - The limits

    302:   Level: intermediate

    304:   Concepts: bar graph^setting axis
    305: @*/
    306: PetscErrorCode  PetscDrawBarSetLimits(PetscDrawBar bar, PetscReal y_min, PetscReal y_max)
    307: {
    310:   bar->ymin = y_min;
    311:   bar->ymax = y_max;
    312:   return(0);
    313: }

    317: /*@C
    318:   PetscDrawBarGetAxis - Gets the axis context associated with a bar graph.
    319:   This is useful if one wants to change some axis property, such as
    320:   labels, color, etc. The axis context should not be destroyed by the
    321:   application code.

    323:   Not Collective (ignored except on processor 0 of PetscDrawBar)

    325:   Input Parameter:
    326: . bar - The bar graph context

    328:   Output Parameter:
    329: . axis - The axis context

    331:   Level: intermediate

    333: @*/
    334: PetscErrorCode  PetscDrawBarGetAxis(PetscDrawBar bar, PetscDrawAxis *axis)
    335: {
    339:   *axis = bar->axis;
    340:   return(0);
    341: }

    345: /*@C
    346:   PetscDrawBarGetDraw - Gets the draw context associated with a bar graph.

    348:   Not Collective, PetscDraw is parallel if PetscDrawBar is parallel

    350:   Input Parameter:
    351: . bar - The bar graph context

    353:   Output Parameter:
    354: . win  - The draw context

    356:   Level: intermediate

    358: @*/
    359: PetscErrorCode  PetscDrawBarGetDraw(PetscDrawBar bar, PetscDraw *win)
    360: {
    364:   *win = bar->win;
    365:   return(0);
    366: }

    370: /*@
    371:     PetscDrawBarSetFromOptions - Sets options related to the PetscDrawBar

    373:     Collective over PetscDrawBar

    375:     Options Database:
    376: .  -bar_sort - sort the entries before drawing the bar graph

    378:     Level: intermediate

    381: .seealso:  PetscDrawBarDestroy(), PetscDrawBarCreate()
    382: @*/
    383: PetscErrorCode  PetscDrawBarSetFromOptions(PetscDrawBar bar)
    384: {
    386:   PetscBool      set;
    387:   PetscReal      tol = bar->sorttolerance;

    390:   PetscOptionsHasName(NULL,"-bar_sort",&set);
    391:   if (set) {
    392:     PetscOptionsGetReal(NULL,"-bar_sort",&tol,NULL);
    393:     PetscDrawBarSort(bar,PETSC_TRUE,tol);
    394:   }
    395:   return(0);
    396: }