Actual source code: dscatter.c

petsc-3.11.4 2019-09-28
Report Typos and Errors

  2: /*
  3:        Contains the data structure for drawing scatter plots
  4:     graphs in a window with an axis. This is intended for scatter
  5:     plots that change dynamically.
  6: */

  8:  #include <petscdraw.h>
  9:  #include <petsc/private/petscimpl.h>

 11: PetscClassId PETSC_DRAWSP_CLASSID = 0;

 13: struct _p_PetscDrawSP {
 14:   PETSCHEADER(int);
 15:   PetscErrorCode (*destroy)(PetscDrawSP);
 16:   PetscErrorCode (*view)(PetscDrawSP,PetscViewer);
 17:   int            len,loc;
 18:   PetscDraw      win;
 19:   PetscDrawAxis  axis;
 20:   PetscReal      xmin,xmax,ymin,ymax,*x,*y;
 21:   int            nopts,dim;
 22: };

 24: #define CHUNCKSIZE 100

 26: /*@C
 27:     PetscDrawSPCreate - Creates a scatter plot data structure.

 29:     Collective on PetscDraw

 31:     Input Parameters:
 32: +   win - the window where the graph will be made.
 33: -   dim - the number of sets of points which will be drawn

 35:     Output Parameters:
 36: .   drawsp - the scatter plot context

 38:    Level: intermediate

 40:    Notes:
 41:     Add points to the plot with PetscDrawSPAddPoint() or PetscDrawSPAddPoints(); the new points are not displayed until PetscDrawSPDraw() is called.

 43:    PetscDrawSPReset() removes all the points that have been added

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

 48:    Concepts: scatter plot^creating

 50: .seealso:  PetscDrawLGCreate(), PetscDrawLG, PetscDrawBarCreate(), PetscDrawBar, PetscDrawHGCreate(), PetscDrawHG, PetscDrawSPDestroy(), PetscDraw, PetscDrawSP, PetscDrawSPSetDimension(), PetscDrawSPReset(),
 51:            PetscDrawSPAddPoint(), PetscDrawSPAddPoints(), PetscDrawSPDraw(), PetscDrawSPSave(), PetscDrawSPSetLimits(), PetscDrawSPGetAxis(),PetscDrawAxis, PetscDrawSPGetDraw()
 52: @*/
 53: PetscErrorCode  PetscDrawSPCreate(PetscDraw draw,int dim,PetscDrawSP *drawsp)
 54: {
 55:   PetscDrawSP    sp;


 63:   PetscHeaderCreate(sp,PETSC_DRAWSP_CLASSID,"DrawSP","Scatter Plot","Draw",PetscObjectComm((PetscObject)draw),PetscDrawSPDestroy,NULL);
 64:   PetscLogObjectParent((PetscObject)draw,(PetscObject)sp);

 66:   PetscObjectReference((PetscObject)draw);
 67:   sp->win = draw;

 69:   sp->view    = NULL;
 70:   sp->destroy = NULL;
 71:   sp->nopts   = 0;
 72:   sp->dim     = dim;
 73:   sp->xmin    = 1.e20;
 74:   sp->ymin    = 1.e20;
 75:   sp->xmax    = -1.e20;
 76:   sp->ymax    = -1.e20;

 78:   PetscMalloc2(dim*CHUNCKSIZE,&sp->x,dim*CHUNCKSIZE,&sp->y);
 79:   PetscLogObjectMemory((PetscObject)sp,2*dim*CHUNCKSIZE*sizeof(PetscReal));

 81:   sp->len     = dim*CHUNCKSIZE;
 82:   sp->loc     = 0;

 84:   PetscDrawAxisCreate(draw,&sp->axis);
 85:   PetscLogObjectParent((PetscObject)sp,(PetscObject)sp->axis);

 87:   *drawsp = sp;
 88:   return(0);
 89: }

 91: /*@
 92:    PetscDrawSPSetDimension - Change the number of sets of points  that are to be drawn.

 94:    Logically Collective on PetscDrawSP

 96:    Input Parameter:
 97: +  sp - the line graph context.
 98: -  dim - the number of curves.

100:    Level: intermediate

102:    Concepts: scatter plot^setting number of data types

104: .seealso: PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPAddPoint(), PetscDrawSPAddPoints()

106: @*/
107: PetscErrorCode  PetscDrawSPSetDimension(PetscDrawSP sp,int dim)
108: {

114:   if (sp->dim == dim) return(0);

116:   PetscFree2(sp->x,sp->y);
117:   sp->dim = dim;
118:   PetscMalloc2(dim*CHUNCKSIZE,&sp->x,dim*CHUNCKSIZE,&sp->y);
119:   PetscLogObjectMemory((PetscObject)sp,2*dim*CHUNCKSIZE*sizeof(PetscReal));
120:   sp->len = dim*CHUNCKSIZE;
121:   return(0);
122: }

124: /*@
125:    PetscDrawSPReset - Clears line graph to allow for reuse with new data.

127:    Logically Collective on PetscDrawSP

129:    Input Parameter:
130: .  sp - the line graph context.

132:    Level: intermediate

134:   Concepts: scatter plot^resetting

136: .seealso: PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPAddPoint(), PetscDrawSPAddPoints(), PetscDrawSPDraw()
137: @*/
138: PetscErrorCode  PetscDrawSPReset(PetscDrawSP sp)
139: {
142:   sp->xmin  = 1.e20;
143:   sp->ymin  = 1.e20;
144:   sp->xmax  = -1.e20;
145:   sp->ymax  = -1.e20;
146:   sp->loc   = 0;
147:   sp->nopts = 0;
148:   return(0);
149: }

151: /*@C
152:    PetscDrawSPDestroy - Frees all space taken up by scatter plot data structure.

154:    Collective on PetscDrawSP

156:    Input Parameter:
157: .  sp - the line graph context

159:    Level: intermediate

161: .seealso:  PetscDrawSPCreate(), PetscDrawSP, PetscDrawSPReset()

163: @*/
164: PetscErrorCode  PetscDrawSPDestroy(PetscDrawSP *sp)
165: {

169:   if (!*sp) return(0);
171:   if (--((PetscObject)(*sp))->refct > 0) {*sp = NULL; return(0);}

173:   PetscFree2((*sp)->x,(*sp)->y);
174:   PetscDrawAxisDestroy(&(*sp)->axis);
175:   PetscDrawDestroy(&(*sp)->win);
176:   PetscHeaderDestroy(sp);
177:   return(0);
178: }

180: /*@
181:    PetscDrawSPAddPoint - Adds another point to each of the scatter plots.

183:    Logically Collective on PetscDrawSP

185:    Input Parameters:
186: +  sp - the scatter plot data structure
187: -  x, y - the points to two vectors containing the new x and y
188:           point for each curve.

190:    Level: intermediate

192:    Notes:
193:     the new points will not be displayed until a call to PetscDrawSPDraw() is made

195:    Concepts: scatter plot^adding points

197: .seealso: PetscDrawSPAddPoints(), PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPReset(), PetscDrawSPDraw()

199: @*/
200: PetscErrorCode  PetscDrawSPAddPoint(PetscDrawSP sp,PetscReal *x,PetscReal *y)
201: {
203:   PetscInt       i;


208:   if (sp->loc+sp->dim >= sp->len) { /* allocate more space */
209:     PetscReal *tmpx,*tmpy;
210:     PetscMalloc2(sp->len+sp->dim*CHUNCKSIZE,&tmpx,sp->len+sp->dim*CHUNCKSIZE,&tmpy);
211:     PetscLogObjectMemory((PetscObject)sp,2*sp->dim*CHUNCKSIZE*sizeof(PetscReal));
212:     PetscMemcpy(tmpx,sp->x,sp->len*sizeof(PetscReal));
213:     PetscMemcpy(tmpy,sp->y,sp->len*sizeof(PetscReal));
214:     PetscFree2(sp->x,sp->y);
215:     sp->x    = tmpx;
216:     sp->y    = tmpy;
217:     sp->len += sp->dim*CHUNCKSIZE;
218:   }
219:   for (i=0; i<sp->dim; i++) {
220:     if (x[i] > sp->xmax) sp->xmax = x[i];
221:     if (x[i] < sp->xmin) sp->xmin = x[i];
222:     if (y[i] > sp->ymax) sp->ymax = y[i];
223:     if (y[i] < sp->ymin) sp->ymin = y[i];

225:     sp->x[sp->loc]   = x[i];
226:     sp->y[sp->loc++] = y[i];
227:   }
228:   sp->nopts++;
229:   return(0);
230: }


233: /*@C
234:    PetscDrawSPAddPoints - Adds several points to each of the scatter plots.

236:    Logically Collective on PetscDrawSP

238:    Input Parameters:
239: +  sp - the LineGraph data structure
240: .  xx,yy - points to two arrays of pointers that point to arrays
241:            containing the new x and y points for each curve.
242: -  n - number of points being added

244:    Level: intermediate

246:    Notes:
247:     the new points will not be displayed until a call to PetscDrawSPDraw() is made

249:    Concepts: scatter plot^adding points

251: .seealso: PetscDrawSPAddPoint(), PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPReset(), PetscDrawSPDraw()
252: @*/
253: PetscErrorCode  PetscDrawSPAddPoints(PetscDrawSP sp,int n,PetscReal **xx,PetscReal **yy)
254: {
256:   PetscInt       i,j,k;
257:   PetscReal      *x,*y;


262:   if (sp->loc+n*sp->dim >= sp->len) { /* allocate more space */
263:     PetscReal *tmpx,*tmpy;
264:     PetscInt  chunk = CHUNCKSIZE;
265:     if (n > chunk) chunk = n;
266:     PetscMalloc2(sp->len+sp->dim*chunk,&tmpx,sp->len+sp->dim*chunk,&tmpy);
267:     PetscLogObjectMemory((PetscObject)sp,2*sp->dim*CHUNCKSIZE*sizeof(PetscReal));
268:     PetscMemcpy(tmpx,sp->x,sp->len*sizeof(PetscReal));
269:     PetscMemcpy(tmpy,sp->y,sp->len*sizeof(PetscReal));
270:     PetscFree2(sp->x,sp->y);

272:     sp->x    = tmpx;
273:     sp->y    = tmpy;
274:     sp->len += sp->dim*CHUNCKSIZE;
275:   }
276:   for (j=0; j<sp->dim; j++) {
277:     x = xx[j]; y = yy[j];
278:     k = sp->loc + j;
279:     for (i=0; i<n; i++) {
280:       if (x[i] > sp->xmax) sp->xmax = x[i];
281:       if (x[i] < sp->xmin) sp->xmin = x[i];
282:       if (y[i] > sp->ymax) sp->ymax = y[i];
283:       if (y[i] < sp->ymin) sp->ymin = y[i];

285:       sp->x[k] = x[i];
286:       sp->y[k] = y[i];
287:       k       += sp->dim;
288:     }
289:   }
290:   sp->loc   += n*sp->dim;
291:   sp->nopts += n;
292:   return(0);
293: }

295: /*@
296:    PetscDrawSPDraw - Redraws a scatter plot.

298:    Collective on PetscDrawSP

300:    Input Parameter:
301: +  sp - the line graph context
302: -  clear - clear the window before drawing the new plot

304:    Level: intermediate

306: .seealso: PetscDrawLGDraw(), PetscDrawLGSPDraw(), PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPReset(), PetscDrawSPAddPoint(), PetscDrawSPAddPoints()

308: @*/
309: PetscErrorCode  PetscDrawSPDraw(PetscDrawSP sp, PetscBool clear)
310: {
311:   PetscReal      xmin,xmax,ymin,ymax;
313:   PetscMPIInt    rank;
314:   PetscBool      isnull;
315:   PetscDraw      draw;

319:   PetscDrawIsNull(sp->win,&isnull);
320:   if (isnull) return(0);
321:   MPI_Comm_rank(PetscObjectComm((PetscObject)sp),&rank);

323:   if (sp->xmin > sp->xmax || sp->ymin > sp->ymax) return(0);
324:   if (sp->nopts < 1) return(0);

326:   draw = sp->win;
327:   if (clear) {
328:     PetscDrawCheckResizedWindow(draw);
329:     PetscDrawClear(draw);
330:   }

332:   xmin = sp->xmin; xmax = sp->xmax; ymin = sp->ymin; ymax = sp->ymax;
333:   PetscDrawAxisSetLimits(sp->axis,xmin,xmax,ymin,ymax);
334:   PetscDrawAxisDraw(sp->axis);

336:   PetscDrawCollectiveBegin(draw);
337:   if (!rank) {
338:     int i,j,dim=sp->dim,nopts=sp->nopts;
339:     for (i=0; i<dim; i++) {
340:       for (j=0; j<nopts; j++) {
341:         PetscDrawPoint(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED);
342:       }
343:     }
344:   }
345:   PetscDrawCollectiveEnd(draw);

347:   PetscDrawFlush(draw);
348:   PetscDrawPause(draw);
349:   return(0);
350: }

352: /*@
353:    PetscDrawSPSave - Saves a drawn image

355:    Collective on PetscDrawSP

357:    Input Parameter:
358: .  sp - the scatter plot context

360:    Level: intermediate

362:    Concepts: scatter plot^saving

364: .seealso:  PetscDrawSPCreate(), PetscDrawSPGetDraw(), PetscDrawSetSave(), PetscDrawSave()
365: @*/
366: PetscErrorCode  PetscDrawSPSave(PetscDrawSP sp)
367: {

372:   PetscDrawSave(sp->win);
373:   return(0);
374: }

376: /*@
377:    PetscDrawSPSetLimits - Sets the axis limits for a scatter plot If more
378:    points are added after this call, the limits will be adjusted to
379:    include those additional points.

381:    Logically Collective on PetscDrawSP

383:    Input Parameters:
384: +  xsp - the line graph context
385: -  x_min,x_max,y_min,y_max - the limits

387:    Level: intermediate

389:    Concepts: scatter plot^setting axis

391: .seealso: PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPDraw(), PetscDrawSPAddPoint(), PetscDrawSPAddPoints(), PetscDrawSPGetAxis()
392: @*/
393: PetscErrorCode  PetscDrawSPSetLimits(PetscDrawSP sp,PetscReal x_min,PetscReal x_max,PetscReal y_min,PetscReal y_max)
394: {
397:   sp->xmin = x_min;
398:   sp->xmax = x_max;
399:   sp->ymin = y_min;
400:   sp->ymax = y_max;
401:   return(0);
402: }

404: /*@C
405:    PetscDrawSPGetAxis - Gets the axis context associated with a line graph.
406:    This is useful if one wants to change some axis property, such as
407:    labels, color, etc. The axis context should not be destroyed by the
408:    application code.

410:    Not Collective, if PetscDrawSP is parallel then PetscDrawAxis is parallel

412:    Input Parameter:
413: .  sp - the line graph context

415:    Output Parameter:
416: .  axis - the axis context

418:    Level: intermediate

420: .seealso: PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPDraw(), PetscDrawSPAddPoint(), PetscDrawSPAddPoints(), PetscDrawAxis, PetscDrawAxisCreate()

422: @*/
423: PetscErrorCode  PetscDrawSPGetAxis(PetscDrawSP sp,PetscDrawAxis *axis)
424: {
428:   *axis = sp->axis;
429:   return(0);
430: }

432: /*@C
433:    PetscDrawSPGetDraw - Gets the draw context associated with a line graph.

435:    Not Collective, PetscDraw is parallel if PetscDrawSP is parallel

437:    Input Parameter:
438: .  sp - the line graph context

440:    Output Parameter:
441: .  draw - the draw context

443:    Level: intermediate

445: .seealso: PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPDraw(), PetscDraw
446: @*/
447: PetscErrorCode  PetscDrawSPGetDraw(PetscDrawSP sp,PetscDraw *draw)
448: {
452:   *draw = sp->win;
453:   return(0);
454: }