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: }