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: struct _p_DrawSP {
11: PETSCHEADER(int)
12: int (*destroy)(PetscDrawSP);
13: int (*view)(PetscDrawSP,PetscViewer);
14: int len,loc;
15: PetscDraw win;
16: PetscDrawAxis axis;
17: PetscReal xmin,xmax,ymin,ymax,*x,*y;
18: int nopts,dim;
19: };
21: #define CHUNCKSIZE 100
23: /*@C
24: PetscDrawSPCreate - Creates a scatter plot data structure.
26: Collective over PetscDraw
28: Input Parameters:
29: + win - the window where the graph will be made.
30: - dim - the number of sets of points which will be drawn
32: Output Parameters:
33: . drawsp - the scatter plot context
35: Level: intermediate
37: Concepts: scatter plot^creating
39: .seealso: PetscDrawSPDestroy()
40: @*/
41: int PetscDrawSPCreate(PetscDraw draw,int dim,PetscDrawSP *drawsp)
42: {
43: int ierr;
44: PetscTruth isnull;
45: PetscObject obj = (PetscObject)draw;
46: PetscDrawSP sp;
51: PetscTypeCompare(obj,PETSC_DRAW_NULL,&isnull);
52: if (isnull) {
53: PetscDrawOpenNull(obj->comm,(PetscDraw*)drawsp);
54: return(0);
55: }
56: PetscHeaderCreate(sp,_p_DrawSP,int,DRAWSP_COOKIE,0,"PetscDrawSP",obj->comm,PetscDrawSPDestroy,0);
57: sp->view = 0;
58: sp->destroy = 0;
59: sp->nopts = 0;
60: sp->win = draw;
61: sp->dim = dim;
62: sp->xmin = 1.e20;
63: sp->ymin = 1.e20;
64: sp->xmax = -1.e20;
65: sp->ymax = -1.e20;
66: PetscMalloc(2*dim*CHUNCKSIZE*sizeof(PetscReal),&sp->x);
67: PetscLogObjectMemory(sp,2*dim*CHUNCKSIZE*sizeof(PetscReal));
68: sp->y = sp->x + dim*CHUNCKSIZE;
69: sp->len = dim*CHUNCKSIZE;
70: sp->loc = 0;
71: PetscDrawAxisCreate(draw,&sp->axis);
72: PetscLogObjectParent(sp,sp->axis);
73: *drawsp = sp;
74: return(0);
75: }
77: /*@
78: PetscDrawSPSetDimension - Change the number of sets of points that are to be drawn.
80: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
82: Input Parameter:
83: + sp - the line graph context.
84: - dim - the number of curves.
86: Level: intermediate
88: Concepts: scatter plot^setting number of data types
90: @*/
91: int PetscDrawSPSetDimension(PetscDrawSP sp,int dim)
92: {
96: if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
98: if (sp->dim == dim) return(0);
100: PetscFree(sp->x);
101: sp->dim = dim;
102: PetscMalloc(2*dim*CHUNCKSIZE*sizeof(PetscReal),&sp->x);
103: PetscLogObjectMemory(sp,2*dim*CHUNCKSIZE*sizeof(PetscReal));
104: sp->y = sp->x + dim*CHUNCKSIZE;
105: sp->len = dim*CHUNCKSIZE;
106: return(0);
107: }
109: /*@
110: PetscDrawSPReset - Clears line graph to allow for reuse with new data.
112: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
114: Input Parameter:
115: . sp - the line graph context.
117: Level: intermediate
119: Concepts: scatter plot^resetting
121: @*/
122: int PetscDrawSPReset(PetscDrawSP sp)
123: {
125: if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
127: sp->xmin = 1.e20;
128: sp->ymin = 1.e20;
129: sp->xmax = -1.e20;
130: sp->ymax = -1.e20;
131: sp->loc = 0;
132: sp->nopts = 0;
133: return(0);
134: }
136: /*@C
137: PetscDrawSPDestroy - Frees all space taken up by scatter plot data structure.
139: Collective over PetscDrawSP
141: Input Parameter:
142: . sp - the line graph context
144: Level: intermediate
146: .seealso: PetscDrawSPCreate()
147: @*/
148: int PetscDrawSPDestroy(PetscDrawSP sp)
149: {
155: if (--sp->refct > 0) return(0);
156: if (sp->cookie == PETSC_DRAW_COOKIE){
157: PetscDrawDestroy((PetscDraw) sp);
158: return(0);
159: }
160: PetscDrawAxisDestroy(sp->axis);
161: PetscFree(sp->x);
162: PetscLogObjectDestroy(sp);
163: PetscHeaderDestroy(sp);
164: return(0);
165: }
167: /*@
168: PetscDrawSPAddPoint - Adds another point to each of the scatter plots.
170: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
172: Input Parameters:
173: + sp - the scatter plot data structure
174: - x, y - the points to two vectors containing the new x and y
175: point for each curve.
177: Level: intermediate
179: Concepts: scatter plot^adding points
181: .seealso: PetscDrawSPAddPoints()
182: @*/
183: int PetscDrawSPAddPoint(PetscDrawSP sp,PetscReal *x,PetscReal *y)
184: {
185: int i,ierr;
188: if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
191: if (sp->loc+sp->dim >= sp->len) { /* allocate more space */
192: PetscReal *tmpx,*tmpy;
193: PetscMalloc((2*sp->len+2*sp->dim*CHUNCKSIZE)*sizeof(PetscReal),&tmpx);
194: PetscLogObjectMemory(sp,2*sp->dim*CHUNCKSIZE*sizeof(PetscReal));
195: tmpy = tmpx + sp->len + sp->dim*CHUNCKSIZE;
196: PetscMemcpy(tmpx,sp->x,sp->len*sizeof(PetscReal));
197: PetscMemcpy(tmpy,sp->y,sp->len*sizeof(PetscReal));
198: PetscFree(sp->x);
199: sp->x = tmpx; sp->y = tmpy;
200: sp->len += sp->dim*CHUNCKSIZE;
201: }
202: for (i=0; i<sp->dim; i++) {
203: if (x[i] > sp->xmax) sp->xmax = x[i];
204: if (x[i] < sp->xmin) sp->xmin = x[i];
205: if (y[i] > sp->ymax) sp->ymax = y[i];
206: if (y[i] < sp->ymin) sp->ymin = y[i];
208: sp->x[sp->loc] = x[i];
209: sp->y[sp->loc++] = y[i];
210: }
211: sp->nopts++;
212: return(0);
213: }
216: /*@C
217: PetscDrawSPAddPoints - Adds several points to each of the scatter plots.
219: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
221: Input Parameters:
222: + sp - the LineGraph data structure
223: . xx,yy - points to two arrays of pointers that point to arrays
224: containing the new x and y points for each curve.
225: - n - number of points being added
227: Level: intermediate
229: Concepts: scatter plot^adding points
231: .seealso: PetscDrawSPAddPoint()
232: @*/
233: int PetscDrawSPAddPoints(PetscDrawSP sp,int n,PetscReal **xx,PetscReal **yy)
234: {
235: int i,j,k,ierr;
236: PetscReal *x,*y;
239: if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
241: if (sp->loc+n*sp->dim >= sp->len) { /* allocate more space */
242: PetscReal *tmpx,*tmpy;
243: int chunk = CHUNCKSIZE;
244: if (n > chunk) chunk = n;
245: PetscMalloc((2*sp->len+2*sp->dim*chunk)*sizeof(PetscReal),&tmpx);
246: PetscLogObjectMemory(sp,2*sp->dim*CHUNCKSIZE*sizeof(PetscReal));
247: tmpy = tmpx + sp->len + sp->dim*chunk;
248: PetscMemcpy(tmpx,sp->x,sp->len*sizeof(PetscReal));
249: PetscMemcpy(tmpy,sp->y,sp->len*sizeof(PetscReal));
250: PetscFree(sp->x);
251: sp->x = tmpx; sp->y = tmpy;
252: sp->len += sp->dim*CHUNCKSIZE;
253: }
254: for (j=0; j<sp->dim; j++) {
255: x = xx[j]; y = yy[j];
256: k = sp->loc + j;
257: for (i=0; i<n; i++) {
258: if (x[i] > sp->xmax) sp->xmax = x[i];
259: if (x[i] < sp->xmin) sp->xmin = x[i];
260: if (y[i] > sp->ymax) sp->ymax = y[i];
261: if (y[i] < sp->ymin) sp->ymin = y[i];
263: sp->x[k] = x[i];
264: sp->y[k] = y[i];
265: k += sp->dim;
266: }
267: }
268: sp->loc += n*sp->dim;
269: sp->nopts += n;
270: return(0);
271: }
273: /*@
274: PetscDrawSPDraw - Redraws a scatter plot.
276: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
278: Input Parameter:
279: . sp - the line graph context
281: Level: intermediate
283: @*/
284: int PetscDrawSPDraw(PetscDrawSP sp)
285: {
286: PetscReal xmin=sp->xmin,xmax=sp->xmax,ymin=sp->ymin,ymax=sp->ymax;
287: int ierr,i,j,dim = sp->dim,nopts = sp->nopts,rank;
288: PetscDraw draw = sp->win;
291: if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
294: if (nopts < 1) return(0);
295: if (xmin > xmax || ymin > ymax) return(0);
296: PetscDrawClear(draw);
297: PetscDrawAxisSetLimits(sp->axis,xmin,xmax,ymin,ymax);
298: PetscDrawAxisDraw(sp->axis);
299:
300: MPI_Comm_rank(sp->comm,&rank);
301: if (rank) return(0);
302: for (i=0; i<dim; i++) {
303: for (j=0; j<nopts; j++) {
304: PetscDrawString(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED,"x");
305: }
306: }
307: PetscDrawFlush(sp->win);
308: PetscDrawPause(sp->win);
309: return(0);
310: }
311:
312: /*@
313: PetscDrawSPSetLimits - Sets the axis limits for a line graph. If more
314: points are added after this call, the limits will be adjusted to
315: include those additional points.
317: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
319: Input Parameters:
320: + xsp - the line graph context
321: - x_min,x_max,y_min,y_max - the limits
323: Level: intermediate
325: Concepts: scatter plot^setting axis
327: @*/
328: int PetscDrawSPSetLimits(PetscDrawSP sp,PetscReal x_min,PetscReal x_max,PetscReal y_min,PetscReal y_max)
329: {
331: if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
333: sp->xmin = x_min;
334: sp->xmax = x_max;
335: sp->ymin = y_min;
336: sp->ymax = y_max;
337: return(0);
338: }
339:
340: /*@C
341: PetscDrawSPGetAxis - Gets the axis context associated with a line graph.
342: This is useful if one wants to change some axis property, such as
343: labels, color, etc. The axis context should not be destroyed by the
344: application code.
346: Not Collective (except PetscDrawAxis can only be used on processor 0 of PetscDrawSP)
348: Input Parameter:
349: . sp - the line graph context
351: Output Parameter:
352: . axis - the axis context
354: Level: intermediate
356: @*/
357: int PetscDrawSPGetAxis(PetscDrawSP sp,PetscDrawAxis *axis)
358: {
360: if (sp && sp->cookie == PETSC_DRAW_COOKIE) {
361: *axis = 0;
362: return(0);
363: }
365: *axis = sp->axis;
366: return(0);
367: }
369: /*@C
370: PetscDrawSPGetDraw - Gets the draw context associated with a line graph.
372: Not Collective, PetscDraw is parallel if PetscDrawSP is parallel
374: Input Parameter:
375: . sp - the line graph context
377: Output Parameter:
378: . draw - the draw context
380: Level: intermediate
382: @*/
383: int PetscDrawSPGetDraw(PetscDrawSP sp,PetscDraw *draw)
384: {
387: if (sp && sp->cookie == PETSC_DRAW_COOKIE) {
388: *draw = (PetscDraw)sp;
389: } else {
390: *draw = sp->win;
391: }
392: return(0);
393: }