Actual source code: dscatter.c

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

  7: #include <petscdraw.h>
  8: #include <petsc/private/drawimpl.h>

 10: PetscClassId PETSC_DRAWSP_CLASSID = 0;

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

 15:     Collective on PetscDraw

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

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

 24:    Level: intermediate

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

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

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

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


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

 48:   PetscObjectReference((PetscObject)draw);
 49:   sp->win = draw;

 51:   sp->view      = NULL;
 52:   sp->destroy   = NULL;
 53:   sp->nopts     = 0;
 54:   sp->dim       = dim;
 55:   sp->xmin      = 1.e20;
 56:   sp->ymin      = 1.e20;
 57:   sp->xmax      = -1.e20;
 58:   sp->ymax      = -1.e20;
 59:   sp->zmax      = 1.;
 60:   sp->zmin      = 1.e20;
 61:   sp->colorized = PETSC_FALSE;

 63:   PetscMalloc3(dim*PETSC_DRAW_SP_CHUNK_SIZE,&sp->x,dim*PETSC_DRAW_SP_CHUNK_SIZE,&sp->y,dim*PETSC_DRAW_SP_CHUNK_SIZE,&sp->z);
 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: {
 94:   if (sp->dim == dim) return 0;

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

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

107:    Logically Collective on PetscDrawSP

109:    Input Parameter:
110: .  sp - the line graph context.

112:    Level: intermediate

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

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

133:    Collective on PetscDrawSP

135:    Input Parameter:
136: .  sp - the line graph context

138:    Level: intermediate

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

142: @*/
143: PetscErrorCode  PetscDrawSPDestroy(PetscDrawSP *sp)
144: {
145:   if (!*sp) return 0;
147:   if (--((PetscObject)(*sp))->refct > 0) {*sp = NULL; return 0;}

149:   PetscFree3((*sp)->x,(*sp)->y,(*sp)->z);
150:   PetscDrawAxisDestroy(&(*sp)->axis);
151:   PetscDrawDestroy(&(*sp)->win);
152:   PetscHeaderDestroy(sp);
153:   return 0;
154: }

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

159:    Logically Collective on PetscDrawSP

161:    Input Parameters:
162: +  sp - the scatter plot data structure
163: -  x, y - two arrays of length dim containing the new x and y coordinate values for each of the curves. Here  dim is the number of curves passed to PetscDrawSPCreate()

165:    Level: intermediate

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

170: .seealso: PetscDrawSPAddPoints(), PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPReset(), PetscDrawSPDraw(), PetscDrawSPAddPointColorized()

172: @*/
173: PetscErrorCode  PetscDrawSPAddPoint(PetscDrawSP sp,PetscReal *x,PetscReal *y)
174: {
175:   PetscInt       i;


179:   if (sp->loc+sp->dim >= sp->len) { /* allocate more space */
180:     PetscReal *tmpx,*tmpy;
181:     PetscMalloc2(sp->len+sp->dim*PETSC_DRAW_SP_CHUNK_SIZE,&tmpx,sp->len+sp->dim*PETSC_DRAW_SP_CHUNK_SIZE,&tmpy);
182:     PetscLogObjectMemory((PetscObject)sp,2*sp->dim*PETSC_DRAW_SP_CHUNK_SIZE*sizeof(PetscReal));
183:     PetscArraycpy(tmpx,sp->x,sp->len);
184:     PetscArraycpy(tmpy,sp->y,sp->len);
185:     PetscFree2(sp->x,sp->y);
186:     sp->x    = tmpx;
187:     sp->y    = tmpy;
188:     sp->len += sp->dim*PETSC_DRAW_SP_CHUNK_SIZE;
189:   }
190:   for (i=0; i<sp->dim; i++) {
191:     if (x[i] > sp->xmax) sp->xmax = x[i];
192:     if (x[i] < sp->xmin) sp->xmin = x[i];
193:     if (y[i] > sp->ymax) sp->ymax = y[i];
194:     if (y[i] < sp->ymin) sp->ymin = y[i];

196:     sp->x[sp->loc]   = x[i];
197:     sp->y[sp->loc++] = y[i];
198:   }
199:   sp->nopts++;
200:   return 0;
201: }

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

206:    Logically Collective on PetscDrawSP

208:    Input Parameters:
209: +  sp - the LineGraph data structure
210: .  xx,yy - points to two arrays of pointers that point to arrays
211:            containing the new x and y points for each curve.
212: -  n - number of points being added

214:    Level: intermediate

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

219: .seealso: PetscDrawSPAddPoint(), PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPReset(), PetscDrawSPDraw(), PetscDrawSPAddPointColorized()
220: @*/
221: PetscErrorCode  PetscDrawSPAddPoints(PetscDrawSP sp,int n,PetscReal **xx,PetscReal **yy)
222: {
223:   PetscInt       i,j,k;
224:   PetscReal      *x,*y;


228:   if (sp->loc+n*sp->dim >= sp->len) { /* allocate more space */
229:     PetscReal *tmpx,*tmpy;
230:     PetscInt  chunk = PETSC_DRAW_SP_CHUNK_SIZE;
231:     if (n > chunk) chunk = n;
232:     PetscMalloc2(sp->len+sp->dim*chunk,&tmpx,sp->len+sp->dim*chunk,&tmpy);
233:     PetscLogObjectMemory((PetscObject)sp,2*sp->dim*PETSC_DRAW_SP_CHUNK_SIZE*sizeof(PetscReal));
234:     PetscArraycpy(tmpx,sp->x,sp->len);
235:     PetscArraycpy(tmpy,sp->y,sp->len);
236:     PetscFree2(sp->x,sp->y);

238:     sp->x    = tmpx;
239:     sp->y    = tmpy;
240:     sp->len += sp->dim*PETSC_DRAW_SP_CHUNK_SIZE;
241:   }
242:   for (j=0; j<sp->dim; j++) {
243:     x = xx[j]; y = yy[j];
244:     k = sp->loc + j;
245:     for (i=0; i<n; i++) {
246:       if (x[i] > sp->xmax) sp->xmax = x[i];
247:       if (x[i] < sp->xmin) sp->xmin = x[i];
248:       if (y[i] > sp->ymax) sp->ymax = y[i];
249:       if (y[i] < sp->ymin) sp->ymin = y[i];

251:       sp->x[k] = x[i];
252:       sp->y[k] = y[i];
253:       k       += sp->dim;
254:     }
255:   }
256:   sp->loc   += n*sp->dim;
257:   sp->nopts += n;
258:   return 0;
259: }

261: /*@
262:    PetscDrawSPAddPointColorized - Adds another point to each of the scatter plots as well as a numeric value to be used to colorize the scatter point.

264:    Logically Collective on PetscDrawSP

266:    Input Parameters:
267: +  sp - the scatter plot data structure
268: . x, y - two arrays of length dim containing the new x and y coordinate values for each of the curves. Here  dim is the number of curves passed to PetscDrawSPCreate()
269: - z - array of length dim containing the numeric values that will be mapped to [0,255] and used for scatter point colors.

271:    Level: intermediate

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

276: .seealso: PetscDrawSPAddPoints(), PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPReset(), PetscDrawSPDraw(), PetscDrawSPAddPoint()

278: @*/
279: PetscErrorCode  PetscDrawSPAddPointColorized(PetscDrawSP sp,PetscReal *x,PetscReal *y,PetscReal *z)
280: {
281:   PetscInt       i;

284:   sp->colorized = PETSC_TRUE;
285:   if (sp->loc+sp->dim >= sp->len) { /* allocate more space */
286:     PetscReal *tmpx,*tmpy,*tmpz;
287:     PetscMalloc3(sp->len+sp->dim*PETSC_DRAW_SP_CHUNK_SIZE,&tmpx,sp->len+sp->dim*PETSC_DRAW_SP_CHUNK_SIZE,&tmpy,sp->len+sp->dim*PETSC_DRAW_SP_CHUNK_SIZE,&tmpz);
288:     PetscLogObjectMemory((PetscObject)sp,2*sp->dim*PETSC_DRAW_SP_CHUNK_SIZE*sizeof(PetscReal));
289:     PetscArraycpy(tmpx,sp->x,sp->len);
290:     PetscArraycpy(tmpy,sp->y,sp->len);
291:     PetscArraycpy(tmpz,sp->z,sp->len);
292:     PetscFree3(sp->x,sp->y,sp->z);
293:     sp->x    = tmpx;
294:     sp->y    = tmpy;
295:     sp->z    = tmpz;
296:     sp->len += sp->dim*PETSC_DRAW_SP_CHUNK_SIZE;
297:   }
298:   for (i=0; i<sp->dim; i++) {
299:     if (x[i] > sp->xmax) sp->xmax = x[i];
300:     if (x[i] < sp->xmin) sp->xmin = x[i];
301:     if (y[i] > sp->ymax) sp->ymax = y[i];
302:     if (y[i] < sp->ymin) sp->ymin = y[i];
303:     if (z[i] < sp->zmin) sp->zmin = z[i];
304:     if (z[i] > sp->zmax) sp->zmax = z[i];
305:     // if (z[i] > sp->zmax && z[i] < 5.) sp->zmax = z[i];

307:     sp->x[sp->loc]   = x[i];
308:     sp->y[sp->loc]   = y[i];
309:     sp->z[sp->loc++] = z[i];
310:   }
311:   sp->nopts++;
312:   return 0;
313: }

315: /*@
316:    PetscDrawSPDraw - Redraws a scatter plot.

318:    Collective on PetscDrawSP

320:    Input Parameters:
321: +  sp - the line graph context
322: -  clear - clear the window before drawing the new plot

324:    Level: intermediate

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

328: @*/
329: PetscErrorCode  PetscDrawSPDraw(PetscDrawSP sp, PetscBool clear)
330: {
331:   PetscReal      xmin,xmax,ymin,ymax;
332:   PetscMPIInt    rank;
333:   PetscInt       color;
334:   PetscBool      isnull;
335:   PetscDraw      draw;

339:   PetscDrawIsNull(sp->win,&isnull);
340:   if (isnull) return 0;
341:   MPI_Comm_rank(PetscObjectComm((PetscObject)sp),&rank);

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

346:   draw = sp->win;
347:   if (clear) {
348:     PetscDrawCheckResizedWindow(draw);
349:     PetscDrawClear(draw);
350:   }

352:   xmin = sp->xmin; xmax = sp->xmax; ymin = sp->ymin; ymax = sp->ymax;
353:   PetscDrawAxisSetLimits(sp->axis,xmin,xmax,ymin,ymax);
354:   PetscDrawAxisDraw(sp->axis);

356:   PetscDrawCollectiveBegin(draw);
357:   if (rank == 0) {
358:     int i,j,dim=sp->dim,nopts=sp->nopts;
359:     for (i=0; i<dim; i++) {
360:       for (j=0; j<nopts; j++) {
361:         if (sp->colorized) {
362:           color = PetscDrawRealToColor(sp->z[j*dim],sp->zmin,sp->zmax);
363:           PetscDrawPoint(draw,sp->x[j*dim+i],sp->y[j*dim+i],color);
364:         } else {
365:           PetscDrawPoint(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED);
366:         }
367:       }
368:     }
369:   }
370:   PetscDrawCollectiveEnd(draw);

372:   PetscDrawFlush(draw);
373:   PetscDrawPause(draw);
374:   return 0;
375: }

377: /*@
378:    PetscDrawSPSave - Saves a drawn image

380:    Collective on PetscDrawSP

382:    Input Parameter:
383: .  sp - the scatter plot context

385:    Level: intermediate

387: .seealso:  PetscDrawSPCreate(), PetscDrawSPGetDraw(), PetscDrawSetSave(), PetscDrawSave()
388: @*/
389: PetscErrorCode  PetscDrawSPSave(PetscDrawSP sp)
390: {
392:   PetscDrawSave(sp->win);
393:   return 0;
394: }

396: /*@
397:    PetscDrawSPSetLimits - Sets the axis limits for a scatter plot If more
398:    points are added after this call, the limits will be adjusted to
399:    include those additional points.

401:    Logically Collective on PetscDrawSP

403:    Input Parameters:
404: +  xsp - the line graph context
405: -  x_min,x_max,y_min,y_max - the limits

407:    Level: intermediate

409: .seealso: PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPDraw(), PetscDrawSPAddPoint(), PetscDrawSPAddPoints(), PetscDrawSPGetAxis()
410: @*/
411: PetscErrorCode  PetscDrawSPSetLimits(PetscDrawSP sp,PetscReal x_min,PetscReal x_max,PetscReal y_min,PetscReal y_max)
412: {
414:   sp->xmin = x_min;
415:   sp->xmax = x_max;
416:   sp->ymin = y_min;
417:   sp->ymax = y_max;
418:   return 0;
419: }

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

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

429:    Input Parameter:
430: .  sp - the line graph context

432:    Output Parameter:
433: .  axis - the axis context

435:    Level: intermediate

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

439: @*/
440: PetscErrorCode  PetscDrawSPGetAxis(PetscDrawSP sp,PetscDrawAxis *axis)
441: {
444:   *axis = sp->axis;
445:   return 0;
446: }

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

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

453:    Input Parameter:
454: .  sp - the line graph context

456:    Output Parameter:
457: .  draw - the draw context

459:    Level: intermediate

461: .seealso: PetscDrawSP, PetscDrawSPCreate(), PetscDrawSPDraw(), PetscDraw
462: @*/
463: PetscErrorCode  PetscDrawSPGetDraw(PetscDrawSP sp,PetscDraw *draw)
464: {
467:   *draw = sp->win;
468:   return 0;
469: }