Actual source code: dscatter.c

petsc-3.7.7 2017-09-25
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>         /*I "petscdraw.h" I*/
  9: #include <petsc/private/petscimpl.h>         /*I "petscsys.h" I*/

 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

 28: /*@C
 29:     PetscDrawSPCreate - Creates a scatter plot data structure.

 31:     Collective on PetscDraw

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

 37:     Output Parameters:
 38: .   drawsp - the scatter plot context

 40:    Level: intermediate

 42:    Concepts: scatter plot^creating

 44: .seealso:  PetscDrawSPDestroy()
 45: @*/
 46: PetscErrorCode  PetscDrawSPCreate(PetscDraw draw,int dim,PetscDrawSP *drawsp)
 47: {
 48:   PetscDrawSP    sp;


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

 59:   PetscObjectReference((PetscObject)draw);
 60:   sp->win = draw;

 62:   sp->view    = NULL;
 63:   sp->destroy = NULL;
 64:   sp->nopts   = 0;
 65:   sp->dim     = dim;
 66:   sp->xmin    = 1.e20;
 67:   sp->ymin    = 1.e20;
 68:   sp->xmax    = -1.e20;
 69:   sp->ymax    = -1.e20;

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

 74:   sp->len     = dim*CHUNCKSIZE;
 75:   sp->loc     = 0;

 77:   PetscDrawAxisCreate(draw,&sp->axis);
 78:   PetscLogObjectParent((PetscObject)sp,(PetscObject)sp->axis);

 80:   *drawsp = sp;
 81:   return(0);
 82: }

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

 89:    Logically Collective on PetscDrawSP

 91:    Input Parameter:
 92: +  sp - the line graph context.
 93: -  dim - the number of curves.

 95:    Level: intermediate

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

 99: @*/
100: PetscErrorCode  PetscDrawSPSetDimension(PetscDrawSP sp,int dim)
101: {

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

109:   PetscFree2(sp->x,sp->y);
110:   sp->dim = dim;
111:   PetscMalloc2(dim*CHUNCKSIZE,&sp->x,dim*CHUNCKSIZE,&sp->y);
112:   PetscLogObjectMemory((PetscObject)sp,2*dim*CHUNCKSIZE*sizeof(PetscReal));
113:   sp->len = dim*CHUNCKSIZE;
114:   return(0);
115: }

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

122:    Logically Collective on PetscDrawSP

124:    Input Parameter:
125: .  sp - the line graph context.

127:    Level: intermediate

129:   Concepts: scatter plot^resetting

131: @*/
132: PetscErrorCode  PetscDrawSPReset(PetscDrawSP sp)
133: {
136:   sp->xmin  = 1.e20;
137:   sp->ymin  = 1.e20;
138:   sp->xmax  = -1.e20;
139:   sp->ymax  = -1.e20;
140:   sp->loc   = 0;
141:   sp->nopts = 0;
142:   return(0);
143: }

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

150:    Collective on PetscDrawSP

152:    Input Parameter:
153: .  sp - the line graph context

155:    Level: intermediate

157: .seealso:  PetscDrawSPCreate()
158: @*/
159: PetscErrorCode  PetscDrawSPDestroy(PetscDrawSP *sp)
160: {

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

168:   PetscFree2((*sp)->x,(*sp)->y);
169:   PetscDrawAxisDestroy(&(*sp)->axis);
170:   PetscDrawDestroy(&(*sp)->win);
171:   PetscHeaderDestroy(sp);
172:   return(0);
173: }

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

180:    Logically Collective on PetscDrawSP

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

187:    Level: intermediate

189:    Concepts: scatter plot^adding points

191: .seealso: PetscDrawSPAddPoints()
192: @*/
193: PetscErrorCode  PetscDrawSPAddPoint(PetscDrawSP sp,PetscReal *x,PetscReal *y)
194: {
196:   PetscInt       i;


201:   if (sp->loc+sp->dim >= sp->len) { /* allocate more space */
202:     PetscReal *tmpx,*tmpy;
203:     PetscMalloc2(sp->len+sp->dim*CHUNCKSIZE,&tmpx,sp->len+sp->dim*CHUNCKSIZE,&tmpy);
204:     PetscLogObjectMemory((PetscObject)sp,2*sp->dim*CHUNCKSIZE*sizeof(PetscReal));
205:     PetscMemcpy(tmpx,sp->x,sp->len*sizeof(PetscReal));
206:     PetscMemcpy(tmpy,sp->y,sp->len*sizeof(PetscReal));
207:     PetscFree2(sp->x,sp->y);
208:     sp->x    = tmpx;
209:     sp->y    = tmpy;
210:     sp->len += sp->dim*CHUNCKSIZE;
211:   }
212:   for (i=0; i<sp->dim; i++) {
213:     if (x[i] > sp->xmax) sp->xmax = x[i];
214:     if (x[i] < sp->xmin) sp->xmin = x[i];
215:     if (y[i] > sp->ymax) sp->ymax = y[i];
216:     if (y[i] < sp->ymin) sp->ymin = y[i];

218:     sp->x[sp->loc]   = x[i];
219:     sp->y[sp->loc++] = y[i];
220:   }
221:   sp->nopts++;
222:   return(0);
223: }


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

231:    Logically Collective on PetscDrawSP

233:    Input Parameters:
234: +  sp - the LineGraph data structure
235: .  xx,yy - points to two arrays of pointers that point to arrays
236:            containing the new x and y points for each curve.
237: -  n - number of points being added

239:    Level: intermediate

241:    Concepts: scatter plot^adding points

243: .seealso: PetscDrawSPAddPoint()
244: @*/
245: PetscErrorCode  PetscDrawSPAddPoints(PetscDrawSP sp,int n,PetscReal **xx,PetscReal **yy)
246: {
248:   PetscInt       i,j,k;
249:   PetscReal      *x,*y;


254:   if (sp->loc+n*sp->dim >= sp->len) { /* allocate more space */
255:     PetscReal *tmpx,*tmpy;
256:     PetscInt  chunk = CHUNCKSIZE;
257:     if (n > chunk) chunk = n;
258:     PetscMalloc2(sp->len+sp->dim*chunk,&tmpx,sp->len+sp->dim*chunk,&tmpy);
259:     PetscLogObjectMemory((PetscObject)sp,2*sp->dim*CHUNCKSIZE*sizeof(PetscReal));
260:     PetscMemcpy(tmpx,sp->x,sp->len*sizeof(PetscReal));
261:     PetscMemcpy(tmpy,sp->y,sp->len*sizeof(PetscReal));
262:     PetscFree2(sp->x,sp->y);

264:     sp->x    = tmpx;
265:     sp->y    = tmpy;
266:     sp->len += sp->dim*CHUNCKSIZE;
267:   }
268:   for (j=0; j<sp->dim; j++) {
269:     x = xx[j]; y = yy[j];
270:     k = sp->loc + j;
271:     for (i=0; i<n; i++) {
272:       if (x[i] > sp->xmax) sp->xmax = x[i];
273:       if (x[i] < sp->xmin) sp->xmin = x[i];
274:       if (y[i] > sp->ymax) sp->ymax = y[i];
275:       if (y[i] < sp->ymin) sp->ymin = y[i];

277:       sp->x[k] = x[i];
278:       sp->y[k] = y[i];
279:       k       += sp->dim;
280:     }
281:   }
282:   sp->loc   += n*sp->dim;
283:   sp->nopts += n;
284:   return(0);
285: }

289: /*@
290:    PetscDrawSPDraw - Redraws a scatter plot.

292:    Collective on PetscDrawSP

294:    Input Parameter:
295: +  sp - the line graph context
296: -  clear - clear the window before drawing the new plot

298:    Level: intermediate

300: .seealso: PetscDrawLGDraw(), PetscDrawLGSPDraw()

302: @*/
303: PetscErrorCode  PetscDrawSPDraw(PetscDrawSP sp, PetscBool clear)
304: {
305:   PetscReal      xmin,xmax,ymin,ymax;
307:   PetscMPIInt    rank;
308:   PetscBool      isnull;
309:   PetscDraw      draw;

313:   PetscDrawIsNull(sp->win,&isnull);
314:   if (isnull) return(0);
315:   MPI_Comm_rank(PetscObjectComm((PetscObject)sp),&rank);

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

320:   draw = sp->win;
321:   if (clear) {
322:     PetscDrawCheckResizedWindow(draw);
323:     PetscDrawClear(draw);
324:   }

326:   xmin = sp->xmin; xmax = sp->xmax; ymin = sp->ymin; ymax = sp->ymax;
327:   PetscDrawAxisSetLimits(sp->axis,xmin,xmax,ymin,ymax);
328:   PetscDrawAxisDraw(sp->axis);

330:   PetscDrawCollectiveBegin(draw);
331:   if (!rank) {
332:     int i,j,dim=sp->dim,nopts=sp->nopts;
333:     for (i=0; i<dim; i++) {
334:       for (j=0; j<nopts; j++) {
335:         PetscDrawPoint(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED);
336:       }
337:     }
338:   }
339:   PetscDrawCollectiveEnd(draw);

341:   PetscDrawFlush(draw);
342:   PetscDrawPause(draw);
343:   return(0);
344: }

348: /*@
349:    PetscDrawSPSave - Saves a drawn image

351:    Collective on PetscDrawSP

353:    Input Parameter:
354: .  sp - the scatter plot context

356:    Level: intermediate

358:    Concepts: scatter plot^saving

360: .seealso:  PetscDrawSPCreate(), PetscDrawSPGetDraw(), PetscDrawSetSave(), PetscDrawSave()
361: @*/
362: PetscErrorCode  PetscDrawSPSave(PetscDrawSP sp)
363: {

368:   PetscDrawSave(sp->win);
369:   return(0);
370: }

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

379:    Logically Collective on PetscDrawSP

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

385:    Level: intermediate

387:    Concepts: scatter plot^setting axis

389: @*/
390: PetscErrorCode  PetscDrawSPSetLimits(PetscDrawSP sp,PetscReal x_min,PetscReal x_max,PetscReal y_min,PetscReal y_max)
391: {
394:   sp->xmin = x_min;
395:   sp->xmax = x_max;
396:   sp->ymin = y_min;
397:   sp->ymax = y_max;
398:   return(0);
399: }

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

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

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

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

417:    Level: intermediate

419: @*/
420: PetscErrorCode  PetscDrawSPGetAxis(PetscDrawSP sp,PetscDrawAxis *axis)
421: {
425:   *axis = sp->axis;
426:   return(0);
427: }

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

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

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

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

442:    Level: intermediate

444: @*/
445: PetscErrorCode  PetscDrawSPGetDraw(PetscDrawSP sp,PetscDraw *draw)
446: {
450:   *draw = sp->win;
451:   return(0);
452: }