Actual source code: bars.c

petsc-3.9.4 2018-09-11
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: Call PetscDrawBarSetData() to provide the bins to be plotted and then PetscDrawBarDraw() to display the new plot

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

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

 47:    Level: intermediate

 49:    Concepts: bar graph^creating

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


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

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

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

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

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

 84: /*@C
 85:    PetscDrawBarSetData

 87:    Logically Collective on PetscDrawBar

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

 95:    Level: intermediate

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

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

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


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

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

125:   Collective over PetscDrawBar

127:   Input Parameter:
128: . bar - The bar graph context

130:   Level: intermediate

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

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

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

151: /*@
152:   PetscDrawBarDraw - Redraws a bar graph.

154:   Collective on PetscDrawBar

156:   Input Parameter:
157: . bar - The bar graph context

159:   Level: intermediate

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

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

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

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

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

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

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

219:   draw = bar->win;
220:   PetscDrawCheckResizedWindow(draw);
221:   PetscDrawClear(draw);

223:   PetscDrawAxisSetLimits(bar->axis,xmin,xmax,ymin,ymax);
224:   PetscDrawAxisDraw(bar->axis);

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

248:   PetscDrawFlush(draw);
249:   PetscDrawPause(draw);
250:   return(0);
251: }

253: /*@
254:   PetscDrawBarSave - Saves a drawn image

256:   Collective on PetscDrawBar

258:   Input Parameters:
259: . bar - The bar graph context

261:   Level: intermediate

263:   Concepts: bar graph^saving

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

273:   PetscDrawSave(bar->win);
274:   return(0);
275: }

277: /*@
278:   PetscDrawBarSetColor - Sets the color the bars will be drawn with.

280:   Logically Collective on PetscDrawBar

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

287:   Level: intermediate

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

291: @*/
292: PetscErrorCode  PetscDrawBarSetColor(PetscDrawBar bar, int color)
293: {
296:   bar->color = color;
297:   return(0);
298: }

300: /*@
301:   PetscDrawBarSort - Sorts the values before drawing the bar chart

303:   Logically Collective on PetscDrawBar

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

310:   Level: intermediate

312:   Concepts: bar graph^setting axis

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

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

330:   Logically Collective on PetscDrawBar

332:   Input Parameters:
333: + bar - The bar graph context
334: - y_min,y_max - The limits

336:   Level: intermediate

338:   Concepts: bar graph^setting axis

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

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

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

359:   Input Parameter:
360: . bar - The bar graph context

362:   Output Parameter:
363: . axis - The axis context

365:   Level: intermediate

367: .seealso: PetscDrawBarCreate(), PetscDrawBar, PetscDrawAxis, PetscDrawAxisCreate()
368: @*/
369: PetscErrorCode  PetscDrawBarGetAxis(PetscDrawBar bar,PetscDrawAxis *axis)
370: {
374:   *axis = bar->axis;
375:   return(0);
376: }

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

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

383:   Input Parameter:
384: . bar - The bar graph context

386:   Output Parameter:
387: . draw  - The draw context

389:   Level: intermediate

391: .seealso: PetscDrawBarCreate(), PetscDrawBar, PetscDrawBarDraw(), PetscDraw
392: @*/
393: PetscErrorCode  PetscDrawBarGetDraw(PetscDrawBar bar,PetscDraw *draw)
394: {
398:   *draw = bar->win;
399:   return(0);
400: }

402: /*@
403:     PetscDrawBarSetFromOptions - Sets options related to the PetscDrawBar

405:     Collective over PetscDrawBar

407:     Options Database:
408: .  -bar_sort - sort the entries before drawing the bar graph

410:     Level: intermediate


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


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