Actual source code: dscatter.c


  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/drawimpl.h>

 11: PetscClassId PETSC_DRAWSP_CLASSID = 0;

 13: /*@C
 14:     PetscDrawSPCreate - Creates a scatter plot data structure.

 16:     Collective on PetscDraw

 18:     Input Parameters:
 19: +   win - the window where the graph will be made.
 20: -   dim - the number of sets of points which will be drawn

 22:     Output Parameters:
 23: .   drawsp - the scatter plot context

 25:    Level: intermediate

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

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

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

 35: .seealso:  PetscDrawLGCreate(), PetscDrawLG, PetscDrawBarCreate(), PetscDrawBar, PetscDrawHGCreate(), PetscDrawHG, PetscDrawSPDestroy(), PetscDraw, PetscDrawSP, PetscDrawSPSetDimension(), PetscDrawSPReset(),
 36:            PetscDrawSPAddPoint(), PetscDrawSPAddPoints(), PetscDrawSPDraw(), PetscDrawSPSave(), PetscDrawSPSetLimits(), PetscDrawSPGetAxis(),PetscDrawAxis, PetscDrawSPGetDraw()
 37: @*/
 38: PetscErrorCode  PetscDrawSPCreate(PetscDraw draw,int dim,PetscDrawSP *drawsp)
 39: {
 40:   PetscDrawSP    sp;


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

 51:   PetscObjectReference((PetscObject)draw);
 52:   sp->win = draw;

 54:   sp->view    = NULL;
 55:   sp->destroy = NULL;
 56:   sp->nopts   = 0;
 57:   sp->dim     = dim;
 58:   sp->xmin    = 1.e20;
 59:   sp->ymin    = 1.e20;
 60:   sp->xmax    = -1.e20;
 61:   sp->ymax    = -1.e20;

 63:   PetscMalloc2(dim*PETSC_DRAW_SP_CHUNK_SIZE,&sp->x,dim*PETSC_DRAW_SP_CHUNK_SIZE,&sp->y);
 64:   PetscLogObjectMemory((PetscObject)sp,2*dim*PETSC_DRAW_SP_CHUNK_SIZE*sizeof(PetscReal));

 66:   sp->len     = dim*PETSC_DRAW_SP_CHUNK_SIZE;
 67:   sp->loc     = 0;

 69:   PetscDrawAxisCreate(draw,&sp->axis);
 70:   PetscLogObjectParent((PetscObject)sp,(PetscObject)sp->axis);

 72:   *drawsp = sp;
 73:   return(0);
 74: }

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

 79:    Logically Collective on PetscDrawSP

 81:    Input Parameters:
 82: +  sp - the line graph context.
 83: -  dim - the number of curves.

 85:    Level: intermediate

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

 89: @*/
 90: PetscErrorCode  PetscDrawSPSetDimension(PetscDrawSP sp,int dim)
 91: {

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

 99:   PetscFree2(sp->x,sp->y);
100:   sp->dim = dim;
101:   PetscMalloc2(dim*PETSC_DRAW_SP_CHUNK_SIZE,&sp->x,dim*PETSC_DRAW_SP_CHUNK_SIZE,&sp->y);
102:   PetscLogObjectMemory((PetscObject)sp,2*dim*PETSC_DRAW_SP_CHUNK_SIZE*sizeof(PetscReal));
103:   sp->len = dim*PETSC_DRAW_SP_CHUNK_SIZE;
104:   return(0);
105: }

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

110:    Logically Collective on PetscDrawSP

112:    Input Parameter:
113: .  sp - the line graph context.

115:    Level: intermediate

117: .seealso: PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPAddPoint(), PetscDrawSPAddPoints(), PetscDrawSPDraw()
118: @*/
119: PetscErrorCode  PetscDrawSPReset(PetscDrawSP sp)
120: {
123:   sp->xmin  = 1.e20;
124:   sp->ymin  = 1.e20;
125:   sp->xmax  = -1.e20;
126:   sp->ymax  = -1.e20;
127:   sp->loc   = 0;
128:   sp->nopts = 0;
129:   return(0);
130: }

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

135:    Collective on PetscDrawSP

137:    Input Parameter:
138: .  sp - the line graph context

140:    Level: intermediate

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

144: @*/
145: PetscErrorCode  PetscDrawSPDestroy(PetscDrawSP *sp)
146: {

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

154:   PetscFree2((*sp)->x,(*sp)->y);
155:   PetscDrawAxisDestroy(&(*sp)->axis);
156:   PetscDrawDestroy(&(*sp)->win);
157:   PetscHeaderDestroy(sp);
158:   return(0);
159: }

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

164:    Logically Collective on PetscDrawSP

166:    Input Parameters:
167: +  sp - the scatter plot data structure
168: -  x, y - the points to two vectors containing the new x and y
169:           point for each curve.

171:    Level: intermediate

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

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

178: @*/
179: PetscErrorCode  PetscDrawSPAddPoint(PetscDrawSP sp,PetscReal *x,PetscReal *y)
180: {
182:   PetscInt       i;


187:   if (sp->loc+sp->dim >= sp->len) { /* allocate more space */
188:     PetscReal *tmpx,*tmpy;
189:     PetscMalloc2(sp->len+sp->dim*PETSC_DRAW_SP_CHUNK_SIZE,&tmpx,sp->len+sp->dim*PETSC_DRAW_SP_CHUNK_SIZE,&tmpy);
190:     PetscLogObjectMemory((PetscObject)sp,2*sp->dim*PETSC_DRAW_SP_CHUNK_SIZE*sizeof(PetscReal));
191:     PetscArraycpy(tmpx,sp->x,sp->len);
192:     PetscArraycpy(tmpy,sp->y,sp->len);
193:     PetscFree2(sp->x,sp->y);
194:     sp->x    = tmpx;
195:     sp->y    = tmpy;
196:     sp->len += sp->dim*PETSC_DRAW_SP_CHUNK_SIZE;
197:   }
198:   for (i=0; i<sp->dim; i++) {
199:     if (x[i] > sp->xmax) sp->xmax = x[i];
200:     if (x[i] < sp->xmin) sp->xmin = x[i];
201:     if (y[i] > sp->ymax) sp->ymax = y[i];
202:     if (y[i] < sp->ymin) sp->ymin = y[i];

204:     sp->x[sp->loc]   = x[i];
205:     sp->y[sp->loc++] = y[i];
206:   }
207:   sp->nopts++;
208:   return(0);
209: }

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

214:    Logically Collective on PetscDrawSP

216:    Input Parameters:
217: +  sp - the LineGraph data structure
218: .  xx,yy - points to two arrays of pointers that point to arrays
219:            containing the new x and y points for each curve.
220: -  n - number of points being added

222:    Level: intermediate

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

227: .seealso: PetscDrawSPAddPoint(), PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPReset(), PetscDrawSPDraw()
228: @*/
229: PetscErrorCode  PetscDrawSPAddPoints(PetscDrawSP sp,int n,PetscReal **xx,PetscReal **yy)
230: {
232:   PetscInt       i,j,k;
233:   PetscReal      *x,*y;


238:   if (sp->loc+n*sp->dim >= sp->len) { /* allocate more space */
239:     PetscReal *tmpx,*tmpy;
240:     PetscInt  chunk = PETSC_DRAW_SP_CHUNK_SIZE;
241:     if (n > chunk) chunk = n;
242:     PetscMalloc2(sp->len+sp->dim*chunk,&tmpx,sp->len+sp->dim*chunk,&tmpy);
243:     PetscLogObjectMemory((PetscObject)sp,2*sp->dim*PETSC_DRAW_SP_CHUNK_SIZE*sizeof(PetscReal));
244:     PetscArraycpy(tmpx,sp->x,sp->len);
245:     PetscArraycpy(tmpy,sp->y,sp->len);
246:     PetscFree2(sp->x,sp->y);

248:     sp->x    = tmpx;
249:     sp->y    = tmpy;
250:     sp->len += sp->dim*PETSC_DRAW_SP_CHUNK_SIZE;
251:   }
252:   for (j=0; j<sp->dim; j++) {
253:     x = xx[j]; y = yy[j];
254:     k = sp->loc + j;
255:     for (i=0; i<n; i++) {
256:       if (x[i] > sp->xmax) sp->xmax = x[i];
257:       if (x[i] < sp->xmin) sp->xmin = x[i];
258:       if (y[i] > sp->ymax) sp->ymax = y[i];
259:       if (y[i] < sp->ymin) sp->ymin = y[i];

261:       sp->x[k] = x[i];
262:       sp->y[k] = y[i];
263:       k       += sp->dim;
264:     }
265:   }
266:   sp->loc   += n*sp->dim;
267:   sp->nopts += n;
268:   return(0);
269: }

271: /*@
272:    PetscDrawSPDraw - Redraws a scatter plot.

274:    Collective on PetscDrawSP

276:    Input Parameters:
277: +  sp - the line graph context
278: -  clear - clear the window before drawing the new plot

280:    Level: intermediate

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

284: @*/
285: PetscErrorCode  PetscDrawSPDraw(PetscDrawSP sp, PetscBool clear)
286: {
287:   PetscReal      xmin,xmax,ymin,ymax;
289:   PetscMPIInt    rank;
290:   PetscBool      isnull;
291:   PetscDraw      draw;

295:   PetscDrawIsNull(sp->win,&isnull);
296:   if (isnull) return(0);
297:   MPI_Comm_rank(PetscObjectComm((PetscObject)sp),&rank);

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

302:   draw = sp->win;
303:   if (clear) {
304:     PetscDrawCheckResizedWindow(draw);
305:     PetscDrawClear(draw);
306:   }

308:   xmin = sp->xmin; xmax = sp->xmax; ymin = sp->ymin; ymax = sp->ymax;
309:   PetscDrawAxisSetLimits(sp->axis,xmin,xmax,ymin,ymax);
310:   PetscDrawAxisDraw(sp->axis);

312:   PetscDrawCollectiveBegin(draw);
313:   if (rank == 0) {
314:     int i,j,dim=sp->dim,nopts=sp->nopts;
315:     for (i=0; i<dim; i++) {
316:       for (j=0; j<nopts; j++) {
317:         PetscDrawPoint(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED);
318:       }
319:     }
320:   }
321:   PetscDrawCollectiveEnd(draw);

323:   PetscDrawFlush(draw);
324:   PetscDrawPause(draw);
325:   return(0);
326: }

328: /*@
329:    PetscDrawSPSave - Saves a drawn image

331:    Collective on PetscDrawSP

333:    Input Parameter:
334: .  sp - the scatter plot context

336:    Level: intermediate

338: .seealso:  PetscDrawSPCreate(), PetscDrawSPGetDraw(), PetscDrawSetSave(), PetscDrawSave()
339: @*/
340: PetscErrorCode  PetscDrawSPSave(PetscDrawSP sp)
341: {

346:   PetscDrawSave(sp->win);
347:   return(0);
348: }

350: /*@
351:    PetscDrawSPSetLimits - Sets the axis limits for a scatter plot If more
352:    points are added after this call, the limits will be adjusted to
353:    include those additional points.

355:    Logically Collective on PetscDrawSP

357:    Input Parameters:
358: +  xsp - the line graph context
359: -  x_min,x_max,y_min,y_max - the limits

361:    Level: intermediate

363: .seealso: PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPDraw(), PetscDrawSPAddPoint(), PetscDrawSPAddPoints(), PetscDrawSPGetAxis()
364: @*/
365: PetscErrorCode  PetscDrawSPSetLimits(PetscDrawSP sp,PetscReal x_min,PetscReal x_max,PetscReal y_min,PetscReal y_max)
366: {
369:   sp->xmin = x_min;
370:   sp->xmax = x_max;
371:   sp->ymin = y_min;
372:   sp->ymax = y_max;
373:   return(0);
374: }

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

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

384:    Input Parameter:
385: .  sp - the line graph context

387:    Output Parameter:
388: .  axis - the axis context

390:    Level: intermediate

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

394: @*/
395: PetscErrorCode  PetscDrawSPGetAxis(PetscDrawSP sp,PetscDrawAxis *axis)
396: {
400:   *axis = sp->axis;
401:   return(0);
402: }

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

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

409:    Input Parameter:
410: .  sp - the line graph context

412:    Output Parameter:
413: .  draw - the draw context

415:    Level: intermediate

417: .seealso: PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPDraw(), PetscDraw
418: @*/
419: PetscErrorCode  PetscDrawSPGetDraw(PetscDrawSP sp,PetscDraw *draw)
420: {
424:   *draw = sp->win;
425:   return(0);
426: }