Actual source code: bars.c

petsc-3.11.4 2019-09-28
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>
  6:  #include <petsc/private/petscimpl.h>
  7:  #include <petscviewer.h>
  8:  #include <../src/sys/classes/draw/utils/axisimpl.h>

 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

 29: /*@C
 30:    PetscDrawBarCreate - Creates a bar graph data structure.

 32:    Collective over PetscDraw

 34:    Input Parameters:
 35: .  draw  - The window where the graph will be made

 37:    Output Parameters:
 38: .  bar - The bar graph context

 40:    Notes:
 41:     Call PetscDrawBarSetData() to provide the bins to be plotted and then PetscDrawBarDraw() to display the new plot

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

 45:    The MPI communicator that owns the PetscDraw owns this PetscDrawBar, but the calls to set options and add data are ignored on all processes except the
 46:    zeroth MPI process in the communicator. All MPI processes in the communicator must call PetscDrawBarDraw() to display the updated graph.

 48:    Level: intermediate

 50:    Concepts: bar graph^creating

 52: .seealso: PetscDrawLGCreate(), PetscDrawLG, PetscDrawSPCreate(), PetscDrawSP, PetscDrawHGCreate(), PetscDrawHG, PetscDrawBarDestroy(), PetscDrawBarSetData(),
 53:           PetscDrawBar, PetscDrawBarDraw(), PetscDrawBarSave(), PetscDrawBarSetColor(), PetscDrawBarSort(), PetscDrawBarSetLimits(), PetscDrawBarGetAxis(), PetscDrawAxis,
 54:           PetscDrawBarGetDraw(), PetscDrawBarSetFromOptions() 
 55: @*/
 56: PetscErrorCode  PetscDrawBarCreate(PetscDraw draw,PetscDrawBar *bar)
 57: {
 58:   PetscDrawBar   h;


 65:   PetscHeaderCreate(h,PETSC_DRAWBAR_CLASSID,"DrawBar","Bar Graph","Draw",PetscObjectComm((PetscObject)draw),PetscDrawBarDestroy,NULL);
 66:   PetscLogObjectParent((PetscObject)draw,(PetscObject)h);

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

 71:   h->view        = NULL;
 72:   h->destroy     = NULL;
 73:   h->color       = PETSC_DRAW_GREEN;
 74:   h->ymin        = 0.;  /* if user has not set these then they are determined from the data */
 75:   h->ymax        = 0.;
 76:   h->numBins     = 0;

 78:   PetscDrawAxisCreate(draw,&h->axis);
 79:   h->axis->xticks = NULL;

 81:   *bar = h;
 82:   return(0);
 83: }

 85: /*@C
 86:    PetscDrawBarSetData

 88:    Logically Collective on PetscDrawBar

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

 96:    Level: intermediate

 98:    Notes:
 99:     Call PetscDrawBarDraw() after this call to display the new plot

101: .seealso: PetscDrawBarCreate(), PetscDrawBar, PetscDrawBarDraw()

103: @*/
104: PetscErrorCode  PetscDrawBarSetData(PetscDrawBar bar,PetscInt bins,const PetscReal data[],const char *const *labels)
105: {


111:   if (bar->numBins != bins) {
112:     PetscFree(bar->values);
113:     PetscMalloc1(bins, &bar->values);
114:     bar->numBins = bins;
115:   }
116:   PetscMemcpy(bar->values,data,bins*sizeof(PetscReal));
117:   bar->numBins = bins;
118:   if (labels) {
119:     PetscStrArrayallocpy(labels,&bar->labels);
120:   }
121:   return(0);
122: }

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

127:   Collective over PetscDrawBar

129:   Input Parameter:
130: . bar - The bar graph context

132:   Level: intermediate

134: .seealso:  PetscDrawBarCreate()
135: @*/
136: PetscErrorCode  PetscDrawBarDestroy(PetscDrawBar *bar)
137: {

141:   if (!*bar) return(0);
143:   if (--((PetscObject)(*bar))->refct > 0) return(0);

145:   PetscFree((*bar)->values);
146:   PetscStrArrayDestroy(&(*bar)->labels);
147:   PetscDrawAxisDestroy(&(*bar)->axis);
148:   PetscDrawDestroy(&(*bar)->win);
149:   PetscHeaderDestroy(bar);
150:   return(0);
151: }

153: /*@
154:   PetscDrawBarDraw - Redraws a bar graph.

156:   Collective on PetscDrawBar

158:   Input Parameter:
159: . bar - The bar graph context

161:   Level: intermediate

163: .seealso: PetscDrawBar, PetscDrawBarCreate(), PetscDrawBarSetData()

165: @*/
166: PetscErrorCode  PetscDrawBarDraw(PetscDrawBar bar)
167: {
168:   PetscDraw      draw;
169:   PetscBool      isnull;
170:   PetscReal      xmin,xmax,ymin,ymax,*values,binLeft,binRight;
171:   PetscInt       numValues,i,bcolor,color,idx,*perm,nplot;
172:   PetscMPIInt    rank;
174:   char           **labels;

178:   PetscDrawIsNull(bar->win,&isnull);
179:   if (isnull) return(0);
180:   MPI_Comm_rank(PetscObjectComm((PetscObject)bar),&rank);

182:   if (bar->numBins < 1) return(0);

184:   color = bar->color;
185:   if (color == PETSC_DRAW_ROTATE) bcolor = PETSC_DRAW_BLACK+1;
186:   else bcolor = color;

188:   numValues = bar->numBins;
189:   values    = bar->values;
190:   if (bar->ymin == bar->ymax) {
191:     /* user has not set bounds on bars so set them based on the data */
192:     ymin = PETSC_MAX_REAL;
193:     ymax = PETSC_MIN_REAL;
194:     for (i=0; i<numValues; i++) {
195:       ymin = PetscMin(ymin,values[i]);
196:       ymax = PetscMax(ymax,values[i]);
197:     }
198:   } else {
199:     ymin = bar->ymin;
200:     ymax = bar->ymax;
201:   }
202:   nplot  = numValues;  /* number of points to actually plot; if some are lower than requested tolerance */
203:   xmin   = 0.0;
204:   xmax   = nplot;
205:   labels = bar->labels;

207:   if (bar->sort) {
208:     PetscMalloc1(numValues,&perm);
209:     for (i=0; i<numValues;i++) perm[i] = i;
210:     PetscSortRealWithPermutation(numValues,values,perm);
211:     if (bar->sorttolerance) {
212:       for (i=0; i<numValues;i++) {
213:         if (values[perm[numValues - i - 1]] < bar->sorttolerance) {
214:           nplot = i;
215:           break;
216:         }
217:       }
218:     }
219:   }

221:   draw = bar->win;
222:   PetscDrawCheckResizedWindow(draw);
223:   PetscDrawClear(draw);

225:   PetscDrawAxisSetLimits(bar->axis,xmin,xmax,ymin,ymax);
226:   PetscDrawAxisDraw(bar->axis);

228:   PetscDrawCollectiveBegin(draw);
229:   if (!rank) { /* Draw bins */
230:     for (i=0; i<nplot; i++) {
231:       idx = (bar->sort ? perm[numValues - i - 1] : i);
232:       binLeft  = xmin + i;
233:       binRight = xmin + i + 1;
234:       PetscDrawRectangle(draw,binLeft,ymin,binRight,values[idx],bcolor,bcolor,bcolor,bcolor);
235:       PetscDrawLine(draw,binLeft,ymin,binLeft,values[idx],PETSC_DRAW_BLACK);
236:       PetscDrawLine(draw,binRight,ymin,binRight,values[idx],PETSC_DRAW_BLACK);
237:       PetscDrawLine(draw,binLeft,values[idx],binRight,values[idx],PETSC_DRAW_BLACK);
238:       if (labels) {
239:         PetscReal h;
240:         PetscDrawStringGetSize(draw,NULL,&h);
241:         PetscDrawStringCentered(draw,.5*(binLeft+binRight),ymin - 1.5*h,bcolor,labels[idx]);
242:       }
243:       if (color == PETSC_DRAW_ROTATE) bcolor++;
244:       if (bcolor > PETSC_DRAW_BASIC_COLORS-1) bcolor = PETSC_DRAW_BLACK+1;
245:     }
246:   }
247:   PetscDrawCollectiveEnd(draw);
248:   if (bar->sort) {PetscFree(perm);}

250:   PetscDrawFlush(draw);
251:   PetscDrawPause(draw);
252:   return(0);
253: }

255: /*@
256:   PetscDrawBarSave - Saves a drawn image

258:   Collective on PetscDrawBar

260:   Input Parameters:
261: . bar - The bar graph context

263:   Level: intermediate

265:   Concepts: bar graph^saving

267: .seealso:  PetscDrawBarCreate(), PetscDrawBarGetDraw(), PetscDrawSetSave(), PetscDrawSave(), PetscDrawBarSetData()
268: @*/
269: PetscErrorCode  PetscDrawBarSave(PetscDrawBar bar)
270: {

275:   PetscDrawSave(bar->win);
276:   return(0);
277: }

279: /*@
280:   PetscDrawBarSetColor - Sets the color the bars will be drawn with.

282:   Logically Collective on PetscDrawBar

284:   Input Parameters:
285: + bar - The bar graph context
286: - color - one of the colors defined in petscdraw.h or PETSC_DRAW_ROTATE to make each bar a
287:           different color

289:   Level: intermediate

291: .seealso: PetscDrawBarCreate(), PetscDrawBar, PetscDrawBarSetData(), PetscDrawBarDraw(), PetscDrawBarGetAxis()

293: @*/
294: PetscErrorCode  PetscDrawBarSetColor(PetscDrawBar bar, int color)
295: {
298:   bar->color = color;
299:   return(0);
300: }

302: /*@
303:   PetscDrawBarSort - Sorts the values before drawing the bar chart

305:   Logically Collective on PetscDrawBar

307:   Input Parameters:
308: + bar - The bar graph context
309: . sort - PETSC_TRUE to sort the values
310: . tolerance - discard values less than tolerance

312:   Level: intermediate

314:   Concepts: bar graph^setting axis

316: .seealso: PetscDrawBarCreate(), PetscDrawBar, PetscDrawBarSetData(), PetscDrawBarSetColor(), PetscDrawBarDraw(), PetscDrawBarGetAxis()
317: @*/
318: PetscErrorCode  PetscDrawBarSort(PetscDrawBar bar, PetscBool sort, PetscReal tolerance)
319: {
322:   bar->sort          = sort;
323:   bar->sorttolerance = tolerance;
324:   return(0);
325: }

327: /*@
328:   PetscDrawBarSetLimits - Sets the axis limits for a bar graph. If more
329:   points are added after this call, the limits will be adjusted to
330:   include those additional points.

332:   Logically Collective on PetscDrawBar

334:   Input Parameters:
335: + bar - The bar graph context
336: - y_min,y_max - The limits

338:   Level: intermediate

340:   Concepts: bar graph^setting axis

342: .seealso: PetscDrawBarCreate(), PetscDrawBar, PetscDrawBarGetAxis(), PetscDrawBarSetData(), PetscDrawBarDraw()
343: @*/
344: PetscErrorCode  PetscDrawBarSetLimits(PetscDrawBar bar, PetscReal y_min, PetscReal y_max)
345: {
348:   bar->ymin = y_min;
349:   bar->ymax = y_max;
350:   return(0);
351: }

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

359:   Not Collective, PetscDrawAxis is parallel if PetscDrawBar is parallel

361:   Input Parameter:
362: . bar - The bar graph context

364:   Output Parameter:
365: . axis - The axis context

367:   Level: intermediate

369: .seealso: PetscDrawBarCreate(), PetscDrawBar, PetscDrawAxis, PetscDrawAxisCreate()
370: @*/
371: PetscErrorCode  PetscDrawBarGetAxis(PetscDrawBar bar,PetscDrawAxis *axis)
372: {
376:   *axis = bar->axis;
377:   return(0);
378: }

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

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

385:   Input Parameter:
386: . bar - The bar graph context

388:   Output Parameter:
389: . draw  - The draw context

391:   Level: intermediate

393: .seealso: PetscDrawBarCreate(), PetscDrawBar, PetscDrawBarDraw(), PetscDraw
394: @*/
395: PetscErrorCode  PetscDrawBarGetDraw(PetscDrawBar bar,PetscDraw *draw)
396: {
400:   *draw = bar->win;
401:   return(0);
402: }

404: /*@
405:     PetscDrawBarSetFromOptions - Sets options related to the PetscDrawBar

407:     Collective over PetscDrawBar

409:     Options Database:
410: .  -bar_sort - sort the entries before drawing the bar graph

412:     Level: intermediate


415: .seealso:  PetscDrawBarDestroy(), PetscDrawBarCreate(), PetscDrawBarSort()
416: @*/
417: PetscErrorCode  PetscDrawBarSetFromOptions(PetscDrawBar bar)
418: {
420:   PetscBool      set;


425:   PetscOptionsHasName(((PetscObject)bar)->options,((PetscObject)bar)->prefix,"-bar_sort",&set);
426:   if (set) {
427:     PetscReal tol = bar->sorttolerance;
428:     PetscOptionsGetReal(((PetscObject)bar)->options,((PetscObject)bar)->prefix,"-bar_sort",&tol,NULL);
429:     PetscDrawBarSort(bar,PETSC_TRUE,tol);
430:   }
431:   return(0);
432: }