Actual source code: dscatter.c
1: /*$Id: dscatter.c,v 1.38 2001/04/10 19:34:23 bsmith Exp $*/
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 petsc.h
10: int DRAWSP_COOKIE;
12: struct _p_DrawSP {
13: PETSCHEADER(int)
14: int (*destroy)(PetscDrawSP);
15: int (*view)(PetscDrawSP,PetscViewer);
16: int len,loc;
17: PetscDraw win;
18: PetscDrawAxis axis;
19: PetscReal xmin,xmax,ymin,ymax,*x,*y;
20: int nopts,dim;
21: };
23: #define CHUNCKSIZE 100
25: /*@C
26: PetscDrawSPCreate - Creates a scatter plot data structure.
28: Collective over PetscDraw
30: Input Parameters:
31: + win - the window where the graph will be made.
32: - dim - the number of sets of points which will be drawn
34: Output Parameters:
35: . drawsp - the scatter plot context
37: Level: intermediate
39: Concepts: scatter plot^creating
41: .seealso: PetscDrawSPDestroy()
42: @*/
43: int PetscDrawSPCreate(PetscDraw draw,int dim,PetscDrawSP *drawsp)
44: {
45: int ierr;
46: PetscTruth isnull;
47: PetscObject obj = (PetscObject)draw;
48: PetscDrawSP sp;
53: PetscTypeCompare(obj,PETSC_DRAW_NULL,&isnull);
54: if (isnull) {
55: PetscDrawOpenNull(obj->comm,(PetscDraw*)drawsp);
56: return(0);
57: }
58: PetscHeaderCreate(sp,_p_DrawSP,int,DRAWSP_COOKIE,0,"PetscDrawSP",obj->comm,PetscDrawSPDestroy,0);
59: sp->view = 0;
60: sp->destroy = 0;
61: sp->nopts = 0;
62: sp->win = draw;
63: sp->dim = dim;
64: sp->xmin = 1.e20;
65: sp->ymin = 1.e20;
66: sp->xmax = -1.e20;
67: sp->ymax = -1.e20;
68: PetscMalloc(2*dim*CHUNCKSIZE*sizeof(PetscReal),&sp->x);
69: PetscLogObjectMemory(sp,2*dim*CHUNCKSIZE*sizeof(PetscReal));
70: sp->y = sp->x + dim*CHUNCKSIZE;
71: sp->len = dim*CHUNCKSIZE;
72: sp->loc = 0;
73: PetscDrawAxisCreate(draw,&sp->axis);
74: PetscLogObjectParent(sp,sp->axis);
75: *drawsp = sp;
76: return(0);
77: }
79: /*@
80: PetscDrawSPSetDimension - Change the number of sets of points that are to be drawn.
82: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
84: Input Parameter:
85: + sp - the line graph context.
86: - dim - the number of curves.
88: Level: intermediate
90: Concepts: scatter plot^setting number of data types
92: @*/
93: int PetscDrawSPSetDimension(PetscDrawSP sp,int dim)
94: {
98: if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
100: if (sp->dim == dim) return(0);
102: PetscFree(sp->x);
103: sp->dim = dim;
104: PetscMalloc(2*dim*CHUNCKSIZE*sizeof(PetscReal),&sp->x);
105: PetscLogObjectMemory(sp,2*dim*CHUNCKSIZE*sizeof(PetscReal));
106: sp->y = sp->x + dim*CHUNCKSIZE;
107: sp->len = dim*CHUNCKSIZE;
108: return(0);
109: }
111: /*@
112: PetscDrawSPReset - Clears line graph to allow for reuse with new data.
114: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
116: Input Parameter:
117: . sp - the line graph context.
119: Level: intermediate
121: Concepts: scatter plot^resetting
123: @*/
124: int PetscDrawSPReset(PetscDrawSP sp)
125: {
127: if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
129: sp->xmin = 1.e20;
130: sp->ymin = 1.e20;
131: sp->xmax = -1.e20;
132: sp->ymax = -1.e20;
133: sp->loc = 0;
134: sp->nopts = 0;
135: return(0);
136: }
138: /*@C
139: PetscDrawSPDestroy - Frees all space taken up by scatter plot data structure.
141: Collective over PetscDrawSP
143: Input Parameter:
144: . sp - the line graph context
146: Level: intermediate
148: .seealso: PetscDrawSPCreate()
149: @*/
150: int PetscDrawSPDestroy(PetscDrawSP sp)
151: {
157: if (--sp->refct > 0) return(0);
158: if (sp->cookie == PETSC_DRAW_COOKIE){
159: PetscDrawDestroy((PetscDraw) sp);
160: return(0);
161: }
162: PetscDrawAxisDestroy(sp->axis);
163: PetscFree(sp->x);
164: PetscLogObjectDestroy(sp);
165: PetscHeaderDestroy(sp);
166: return(0);
167: }
169: /*@
170: PetscDrawSPAddPoint - Adds another point to each of the scatter plots.
172: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
174: Input Parameters:
175: + sp - the scatter plot data structure
176: - x, y - the points to two vectors containing the new x and y
177: point for each curve.
179: Level: intermediate
181: Concepts: scatter plot^adding points
183: .seealso: PetscDrawSPAddPoints()
184: @*/
185: int PetscDrawSPAddPoint(PetscDrawSP sp,PetscReal *x,PetscReal *y)
186: {
187: int i,ierr;
190: if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
193: if (sp->loc+sp->dim >= sp->len) { /* allocate more space */
194: PetscReal *tmpx,*tmpy;
195: PetscMalloc((2*sp->len+2*sp->dim*CHUNCKSIZE)*sizeof(PetscReal),&tmpx);
196: PetscLogObjectMemory(sp,2*sp->dim*CHUNCKSIZE*sizeof(PetscReal));
197: tmpy = tmpx + sp->len + sp->dim*CHUNCKSIZE;
198: PetscMemcpy(tmpx,sp->x,sp->len*sizeof(PetscReal));
199: PetscMemcpy(tmpy,sp->y,sp->len*sizeof(PetscReal));
200: PetscFree(sp->x);
201: sp->x = tmpx; sp->y = tmpy;
202: sp->len += sp->dim*CHUNCKSIZE;
203: }
204: for (i=0; i<sp->dim; i++) {
205: if (x[i] > sp->xmax) sp->xmax = x[i];
206: if (x[i] < sp->xmin) sp->xmin = x[i];
207: if (y[i] > sp->ymax) sp->ymax = y[i];
208: if (y[i] < sp->ymin) sp->ymin = y[i];
210: sp->x[sp->loc] = x[i];
211: sp->y[sp->loc++] = y[i];
212: }
213: sp->nopts++;
214: return(0);
215: }
218: /*@C
219: PetscDrawSPAddPoints - Adds several points to each of the scatter plots.
221: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
223: Input Parameters:
224: + sp - the LineGraph data structure
225: . xx,yy - points to two arrays of pointers that point to arrays
226: containing the new x and y points for each curve.
227: - n - number of points being added
229: Level: intermediate
231: Concepts: scatter plot^adding points
233: .seealso: PetscDrawSPAddPoint()
234: @*/
235: int PetscDrawSPAddPoints(PetscDrawSP sp,int n,PetscReal **xx,PetscReal **yy)
236: {
237: int i,j,k,ierr;
238: PetscReal *x,*y;
241: if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
243: if (sp->loc+n*sp->dim >= sp->len) { /* allocate more space */
244: PetscReal *tmpx,*tmpy;
245: int chunk = CHUNCKSIZE;
246: if (n > chunk) chunk = n;
247: PetscMalloc((2*sp->len+2*sp->dim*chunk)*sizeof(PetscReal),&tmpx);
248: PetscLogObjectMemory(sp,2*sp->dim*CHUNCKSIZE*sizeof(PetscReal));
249: tmpy = tmpx + sp->len + sp->dim*chunk;
250: PetscMemcpy(tmpx,sp->x,sp->len*sizeof(PetscReal));
251: PetscMemcpy(tmpy,sp->y,sp->len*sizeof(PetscReal));
252: PetscFree(sp->x);
253: sp->x = tmpx; sp->y = tmpy;
254: sp->len += sp->dim*CHUNCKSIZE;
255: }
256: for (j=0; j<sp->dim; j++) {
257: x = xx[j]; y = yy[j];
258: k = sp->loc + j;
259: for (i=0; i<n; i++) {
260: if (x[i] > sp->xmax) sp->xmax = x[i];
261: if (x[i] < sp->xmin) sp->xmin = x[i];
262: if (y[i] > sp->ymax) sp->ymax = y[i];
263: if (y[i] < sp->ymin) sp->ymin = y[i];
265: sp->x[k] = x[i];
266: sp->y[k] = y[i];
267: k += sp->dim;
268: }
269: }
270: sp->loc += n*sp->dim;
271: sp->nopts += n;
272: return(0);
273: }
275: /*@
276: PetscDrawSPDraw - Redraws a scatter plot.
278: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
280: Input Parameter:
281: . sp - the line graph context
283: Level: intermediate
285: @*/
286: int PetscDrawSPDraw(PetscDrawSP sp)
287: {
288: PetscReal xmin=sp->xmin,xmax=sp->xmax,ymin=sp->ymin,ymax=sp->ymax;
289: int ierr,i,j,dim = sp->dim,nopts = sp->nopts,rank;
290: PetscDraw draw = sp->win;
293: if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
296: if (nopts < 1) return(0);
297: if (xmin > xmax || ymin > ymax) return(0);
298: PetscDrawClear(draw);
299: PetscDrawAxisSetLimits(sp->axis,xmin,xmax,ymin,ymax);
300: PetscDrawAxisDraw(sp->axis);
301:
302: MPI_Comm_rank(sp->comm,&rank);
303: if (rank) return(0);
304: for (i=0; i<dim; i++) {
305: for (j=0; j<nopts; j++) {
306: PetscDrawString(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED,"x");
307: }
308: }
309: PetscDrawFlush(sp->win);
310: PetscDrawPause(sp->win);
311: return(0);
312: }
313:
314: /*@
315: PetscDrawSPSetLimits - Sets the axis limits for a line graph. If more
316: points are added after this call, the limits will be adjusted to
317: include those additional points.
319: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
321: Input Parameters:
322: + xsp - the line graph context
323: - x_min,x_max,y_min,y_max - the limits
325: Level: intermediate
327: Concepts: scatter plot^setting axis
329: @*/
330: int PetscDrawSPSetLimits(PetscDrawSP sp,PetscReal x_min,PetscReal x_max,PetscReal y_min,PetscReal y_max)
331: {
333: if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
335: sp->xmin = x_min;
336: sp->xmax = x_max;
337: sp->ymin = y_min;
338: sp->ymax = y_max;
339: return(0);
340: }
341:
342: /*@C
343: PetscDrawSPGetAxis - Gets the axis context associated with a line graph.
344: This is useful if one wants to change some axis property, such as
345: labels, color, etc. The axis context should not be destroyed by the
346: application code.
348: Not Collective (except PetscDrawAxis can only be used on processor 0 of PetscDrawSP)
350: Input Parameter:
351: . sp - the line graph context
353: Output Parameter:
354: . axis - the axis context
356: Level: intermediate
358: @*/
359: int PetscDrawSPGetAxis(PetscDrawSP sp,PetscDrawAxis *axis)
360: {
362: if (sp && sp->cookie == PETSC_DRAW_COOKIE) {
363: *axis = 0;
364: return(0);
365: }
367: *axis = sp->axis;
368: return(0);
369: }
371: /*@C
372: PetscDrawSPGetDraw - Gets the draw context associated with a line graph.
374: Not Collective, PetscDraw is parallel if PetscDrawSP is parallel
376: Input Parameter:
377: . sp - the line graph context
379: Output Parameter:
380: . draw - the draw context
382: Level: intermediate
384: @*/
385: int PetscDrawSPGetDraw(PetscDrawSP sp,PetscDraw *draw)
386: {
389: if (sp && sp->cookie == PETSC_DRAW_COOKIE) {
390: *draw = (PetscDraw)sp;
391: } else {
392: *draw = sp->win;
393: }
394: return(0);
395: }