xref: /petsc/src/sys/classes/draw/utils/dscatter.c (revision 5c6c1daec53e1d9ab0bec9db5309fd8fc7645b8d)
1*5c6c1daeSBarry Smith 
2*5c6c1daeSBarry Smith /*
3*5c6c1daeSBarry Smith        Contains the data structure for drawing scatter plots
4*5c6c1daeSBarry Smith     graphs in a window with an axis. This is intended for scatter
5*5c6c1daeSBarry Smith     plots that change dynamically.
6*5c6c1daeSBarry Smith */
7*5c6c1daeSBarry Smith 
8*5c6c1daeSBarry Smith #include <petscsys.h>         /*I "petscsys.h" I*/
9*5c6c1daeSBarry Smith 
10*5c6c1daeSBarry Smith PetscClassId PETSC_DRAWSP_CLASSID = 0;
11*5c6c1daeSBarry Smith 
12*5c6c1daeSBarry Smith struct _p_PetscDrawSP {
13*5c6c1daeSBarry Smith   PETSCHEADER(int);
14*5c6c1daeSBarry Smith   PetscErrorCode (*destroy)(PetscDrawSP);
15*5c6c1daeSBarry Smith   PetscErrorCode (*view)(PetscDrawSP,PetscViewer);
16*5c6c1daeSBarry Smith   int           len,loc;
17*5c6c1daeSBarry Smith   PetscDraw     win;
18*5c6c1daeSBarry Smith   PetscDrawAxis axis;
19*5c6c1daeSBarry Smith   PetscReal     xmin,xmax,ymin,ymax,*x,*y;
20*5c6c1daeSBarry Smith   int           nopts,dim;
21*5c6c1daeSBarry Smith };
22*5c6c1daeSBarry Smith 
23*5c6c1daeSBarry Smith #define CHUNCKSIZE 100
24*5c6c1daeSBarry Smith 
25*5c6c1daeSBarry Smith #undef __FUNCT__
26*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSPCreate"
27*5c6c1daeSBarry Smith /*@C
28*5c6c1daeSBarry Smith     PetscDrawSPCreate - Creates a scatter plot data structure.
29*5c6c1daeSBarry Smith 
30*5c6c1daeSBarry Smith     Collective over PetscDraw
31*5c6c1daeSBarry Smith 
32*5c6c1daeSBarry Smith     Input Parameters:
33*5c6c1daeSBarry Smith +   win - the window where the graph will be made.
34*5c6c1daeSBarry Smith -   dim - the number of sets of points which will be drawn
35*5c6c1daeSBarry Smith 
36*5c6c1daeSBarry Smith     Output Parameters:
37*5c6c1daeSBarry Smith .   drawsp - the scatter plot context
38*5c6c1daeSBarry Smith 
39*5c6c1daeSBarry Smith    Level: intermediate
40*5c6c1daeSBarry Smith 
41*5c6c1daeSBarry Smith    Concepts: scatter plot^creating
42*5c6c1daeSBarry Smith 
43*5c6c1daeSBarry Smith .seealso:  PetscDrawSPDestroy()
44*5c6c1daeSBarry Smith @*/
45*5c6c1daeSBarry Smith PetscErrorCode  PetscDrawSPCreate(PetscDraw draw,int dim,PetscDrawSP *drawsp)
46*5c6c1daeSBarry Smith {
47*5c6c1daeSBarry Smith   PetscErrorCode ierr;
48*5c6c1daeSBarry Smith   PetscBool      isnull;
49*5c6c1daeSBarry Smith   PetscObject    obj = (PetscObject)draw;
50*5c6c1daeSBarry Smith   PetscDrawSP    sp;
51*5c6c1daeSBarry Smith 
52*5c6c1daeSBarry Smith   PetscFunctionBegin;
53*5c6c1daeSBarry Smith   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
54*5c6c1daeSBarry Smith   PetscValidPointer(drawsp,3);
55*5c6c1daeSBarry Smith   ierr = PetscObjectTypeCompare(obj,PETSC_DRAW_NULL,&isnull);CHKERRQ(ierr);
56*5c6c1daeSBarry Smith   if (isnull) {
57*5c6c1daeSBarry Smith     ierr = PetscDrawOpenNull(((PetscObject)obj)->comm,(PetscDraw*)drawsp);CHKERRQ(ierr);
58*5c6c1daeSBarry Smith     PetscFunctionReturn(0);
59*5c6c1daeSBarry Smith   }
60*5c6c1daeSBarry Smith   ierr = PetscHeaderCreate(sp,_p_PetscDrawSP,int,PETSC_DRAWSP_CLASSID,0,"PetscDrawSP","Scatter plot","Draw",((PetscObject)obj)->comm,PetscDrawSPDestroy,0);CHKERRQ(ierr);
61*5c6c1daeSBarry Smith   sp->view    = 0;
62*5c6c1daeSBarry Smith   sp->destroy = 0;
63*5c6c1daeSBarry Smith   sp->nopts   = 0;
64*5c6c1daeSBarry Smith   sp->win     = draw;
65*5c6c1daeSBarry Smith   sp->dim     = dim;
66*5c6c1daeSBarry Smith   sp->xmin    = 1.e20;
67*5c6c1daeSBarry Smith   sp->ymin    = 1.e20;
68*5c6c1daeSBarry Smith   sp->xmax    = -1.e20;
69*5c6c1daeSBarry Smith   sp->ymax    = -1.e20;
70*5c6c1daeSBarry Smith   ierr = PetscMalloc2(dim*CHUNCKSIZE,PetscReal,&sp->x,dim*CHUNCKSIZE,PetscReal,&sp->y);CHKERRQ(ierr);
71*5c6c1daeSBarry Smith   ierr = PetscLogObjectMemory(sp,2*dim*CHUNCKSIZE*sizeof(PetscReal));CHKERRQ(ierr);
72*5c6c1daeSBarry Smith   sp->len     = dim*CHUNCKSIZE;
73*5c6c1daeSBarry Smith   sp->loc     = 0;
74*5c6c1daeSBarry Smith   ierr = PetscDrawAxisCreate(draw,&sp->axis);CHKERRQ(ierr);
75*5c6c1daeSBarry Smith   ierr = PetscLogObjectParent(sp,sp->axis);CHKERRQ(ierr);
76*5c6c1daeSBarry Smith   *drawsp = sp;
77*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
78*5c6c1daeSBarry Smith }
79*5c6c1daeSBarry Smith 
80*5c6c1daeSBarry Smith #undef __FUNCT__
81*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSPSetDimension"
82*5c6c1daeSBarry Smith /*@
83*5c6c1daeSBarry Smith    PetscDrawSPSetDimension - Change the number of sets of points  that are to be drawn.
84*5c6c1daeSBarry Smith 
85*5c6c1daeSBarry Smith    Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
86*5c6c1daeSBarry Smith 
87*5c6c1daeSBarry Smith    Input Parameter:
88*5c6c1daeSBarry Smith +  sp - the line graph context.
89*5c6c1daeSBarry Smith -  dim - the number of curves.
90*5c6c1daeSBarry Smith 
91*5c6c1daeSBarry Smith    Level: intermediate
92*5c6c1daeSBarry Smith 
93*5c6c1daeSBarry Smith    Concepts: scatter plot^setting number of data types
94*5c6c1daeSBarry Smith 
95*5c6c1daeSBarry Smith @*/
96*5c6c1daeSBarry Smith PetscErrorCode  PetscDrawSPSetDimension(PetscDrawSP sp,int dim)
97*5c6c1daeSBarry Smith {
98*5c6c1daeSBarry Smith   PetscErrorCode ierr;
99*5c6c1daeSBarry Smith 
100*5c6c1daeSBarry Smith   PetscFunctionBegin;
101*5c6c1daeSBarry Smith   if (sp && ((PetscObject)sp)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
102*5c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp,PETSC_DRAWSP_CLASSID,1);
103*5c6c1daeSBarry Smith   if (sp->dim == dim) PetscFunctionReturn(0);
104*5c6c1daeSBarry Smith 
105*5c6c1daeSBarry Smith   ierr = PetscFree2(sp->x,sp->y);CHKERRQ(ierr);
106*5c6c1daeSBarry Smith   sp->dim     = dim;
107*5c6c1daeSBarry Smith   ierr = PetscMalloc2(dim*CHUNCKSIZE,PetscReal,&sp->x,dim*CHUNCKSIZE,PetscReal,&sp->y);CHKERRQ(ierr);
108*5c6c1daeSBarry Smith   ierr = PetscLogObjectMemory(sp,2*dim*CHUNCKSIZE*sizeof(PetscReal));CHKERRQ(ierr);
109*5c6c1daeSBarry Smith   sp->len     = dim*CHUNCKSIZE;
110*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
111*5c6c1daeSBarry Smith }
112*5c6c1daeSBarry Smith 
113*5c6c1daeSBarry Smith #undef __FUNCT__
114*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSPReset"
115*5c6c1daeSBarry Smith /*@
116*5c6c1daeSBarry Smith    PetscDrawSPReset - Clears line graph to allow for reuse with new data.
117*5c6c1daeSBarry Smith 
118*5c6c1daeSBarry Smith    Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
119*5c6c1daeSBarry Smith 
120*5c6c1daeSBarry Smith    Input Parameter:
121*5c6c1daeSBarry Smith .  sp - the line graph context.
122*5c6c1daeSBarry Smith 
123*5c6c1daeSBarry Smith    Level: intermediate
124*5c6c1daeSBarry Smith 
125*5c6c1daeSBarry Smith   Concepts: scatter plot^resetting
126*5c6c1daeSBarry Smith 
127*5c6c1daeSBarry Smith @*/
128*5c6c1daeSBarry Smith PetscErrorCode  PetscDrawSPReset(PetscDrawSP sp)
129*5c6c1daeSBarry Smith {
130*5c6c1daeSBarry Smith   PetscFunctionBegin;
131*5c6c1daeSBarry Smith   if (sp && ((PetscObject)sp)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
132*5c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp,PETSC_DRAWSP_CLASSID,1);
133*5c6c1daeSBarry Smith   sp->xmin  = 1.e20;
134*5c6c1daeSBarry Smith   sp->ymin  = 1.e20;
135*5c6c1daeSBarry Smith   sp->xmax  = -1.e20;
136*5c6c1daeSBarry Smith   sp->ymax  = -1.e20;
137*5c6c1daeSBarry Smith   sp->loc   = 0;
138*5c6c1daeSBarry Smith   sp->nopts = 0;
139*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
140*5c6c1daeSBarry Smith }
141*5c6c1daeSBarry Smith 
142*5c6c1daeSBarry Smith #undef __FUNCT__
143*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSPDestroy"
144*5c6c1daeSBarry Smith /*@C
145*5c6c1daeSBarry Smith    PetscDrawSPDestroy - Frees all space taken up by scatter plot data structure.
146*5c6c1daeSBarry Smith 
147*5c6c1daeSBarry Smith    Collective over PetscDrawSP
148*5c6c1daeSBarry Smith 
149*5c6c1daeSBarry Smith    Input Parameter:
150*5c6c1daeSBarry Smith .  sp - the line graph context
151*5c6c1daeSBarry Smith 
152*5c6c1daeSBarry Smith    Level: intermediate
153*5c6c1daeSBarry Smith 
154*5c6c1daeSBarry Smith .seealso:  PetscDrawSPCreate()
155*5c6c1daeSBarry Smith @*/
156*5c6c1daeSBarry Smith PetscErrorCode  PetscDrawSPDestroy(PetscDrawSP *sp)
157*5c6c1daeSBarry Smith {
158*5c6c1daeSBarry Smith   PetscErrorCode ierr;
159*5c6c1daeSBarry Smith 
160*5c6c1daeSBarry Smith   PetscFunctionBegin;
161*5c6c1daeSBarry Smith   if (!*sp) PetscFunctionReturn(0);
162*5c6c1daeSBarry Smith   PetscValidHeader(*sp,1);
163*5c6c1daeSBarry Smith 
164*5c6c1daeSBarry Smith   if (--((PetscObject)(*sp))->refct > 0) PetscFunctionReturn(0);
165*5c6c1daeSBarry Smith   if (((PetscObject)(*sp))->classid == PETSC_DRAW_CLASSID){
166*5c6c1daeSBarry Smith     ierr = PetscDrawDestroy((PetscDraw*) sp);CHKERRQ(ierr);
167*5c6c1daeSBarry Smith     PetscFunctionReturn(0);
168*5c6c1daeSBarry Smith   }
169*5c6c1daeSBarry Smith   ierr = PetscDrawAxisDestroy(&(*sp)->axis);CHKERRQ(ierr);
170*5c6c1daeSBarry Smith   ierr = PetscFree2((*sp)->x,(*sp)->y);CHKERRQ(ierr);
171*5c6c1daeSBarry Smith   ierr = PetscHeaderDestroy(sp);CHKERRQ(ierr);
172*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
173*5c6c1daeSBarry Smith }
174*5c6c1daeSBarry Smith 
175*5c6c1daeSBarry Smith #undef __FUNCT__
176*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSPAddPoint"
177*5c6c1daeSBarry Smith /*@
178*5c6c1daeSBarry Smith    PetscDrawSPAddPoint - Adds another point to each of the scatter plots.
179*5c6c1daeSBarry Smith 
180*5c6c1daeSBarry Smith    Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
181*5c6c1daeSBarry Smith 
182*5c6c1daeSBarry Smith    Input Parameters:
183*5c6c1daeSBarry Smith +  sp - the scatter plot data structure
184*5c6c1daeSBarry Smith -  x, y - the points to two vectors containing the new x and y
185*5c6c1daeSBarry Smith           point for each curve.
186*5c6c1daeSBarry Smith 
187*5c6c1daeSBarry Smith    Level: intermediate
188*5c6c1daeSBarry Smith 
189*5c6c1daeSBarry Smith    Concepts: scatter plot^adding points
190*5c6c1daeSBarry Smith 
191*5c6c1daeSBarry Smith .seealso: PetscDrawSPAddPoints()
192*5c6c1daeSBarry Smith @*/
193*5c6c1daeSBarry Smith PetscErrorCode  PetscDrawSPAddPoint(PetscDrawSP sp,PetscReal *x,PetscReal *y)
194*5c6c1daeSBarry Smith {
195*5c6c1daeSBarry Smith   PetscErrorCode ierr;
196*5c6c1daeSBarry Smith   PetscInt       i;
197*5c6c1daeSBarry Smith 
198*5c6c1daeSBarry Smith   PetscFunctionBegin;
199*5c6c1daeSBarry Smith   if (sp && ((PetscObject)sp)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
200*5c6c1daeSBarry Smith 
201*5c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp,PETSC_DRAWSP_CLASSID,1);
202*5c6c1daeSBarry Smith   if (sp->loc+sp->dim >= sp->len) { /* allocate more space */
203*5c6c1daeSBarry Smith     PetscReal *tmpx,*tmpy;
204*5c6c1daeSBarry Smith     ierr = PetscMalloc2(sp->len+sp->dim*CHUNCKSIZE,PetscReal,&tmpx,sp->len+sp->dim*CHUNCKSIZE,PetscReal,&tmpy);CHKERRQ(ierr);
205*5c6c1daeSBarry Smith     ierr = PetscLogObjectMemory(sp,2*sp->dim*CHUNCKSIZE*sizeof(PetscReal));CHKERRQ(ierr);
206*5c6c1daeSBarry Smith     ierr = PetscMemcpy(tmpx,sp->x,sp->len*sizeof(PetscReal));CHKERRQ(ierr);
207*5c6c1daeSBarry Smith     ierr = PetscMemcpy(tmpy,sp->y,sp->len*sizeof(PetscReal));CHKERRQ(ierr);
208*5c6c1daeSBarry Smith     ierr = PetscFree2(sp->x,sp->y);CHKERRQ(ierr);
209*5c6c1daeSBarry Smith     sp->x = tmpx;
210*5c6c1daeSBarry Smith     sp->y = tmpy;
211*5c6c1daeSBarry Smith     sp->len += sp->dim*CHUNCKSIZE;
212*5c6c1daeSBarry Smith   }
213*5c6c1daeSBarry Smith   for (i=0; i<sp->dim; i++) {
214*5c6c1daeSBarry Smith     if (x[i] > sp->xmax) sp->xmax = x[i];
215*5c6c1daeSBarry Smith     if (x[i] < sp->xmin) sp->xmin = x[i];
216*5c6c1daeSBarry Smith     if (y[i] > sp->ymax) sp->ymax = y[i];
217*5c6c1daeSBarry Smith     if (y[i] < sp->ymin) sp->ymin = y[i];
218*5c6c1daeSBarry Smith 
219*5c6c1daeSBarry Smith     sp->x[sp->loc]   = x[i];
220*5c6c1daeSBarry Smith     sp->y[sp->loc++] = y[i];
221*5c6c1daeSBarry Smith   }
222*5c6c1daeSBarry Smith   sp->nopts++;
223*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
224*5c6c1daeSBarry Smith }
225*5c6c1daeSBarry Smith 
226*5c6c1daeSBarry Smith 
227*5c6c1daeSBarry Smith #undef __FUNCT__
228*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSPAddPoints"
229*5c6c1daeSBarry Smith /*@C
230*5c6c1daeSBarry Smith    PetscDrawSPAddPoints - Adds several points to each of the scatter plots.
231*5c6c1daeSBarry Smith 
232*5c6c1daeSBarry Smith    Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
233*5c6c1daeSBarry Smith 
234*5c6c1daeSBarry Smith    Input Parameters:
235*5c6c1daeSBarry Smith +  sp - the LineGraph data structure
236*5c6c1daeSBarry Smith .  xx,yy - points to two arrays of pointers that point to arrays
237*5c6c1daeSBarry Smith            containing the new x and y points for each curve.
238*5c6c1daeSBarry Smith -  n - number of points being added
239*5c6c1daeSBarry Smith 
240*5c6c1daeSBarry Smith    Level: intermediate
241*5c6c1daeSBarry Smith 
242*5c6c1daeSBarry Smith    Concepts: scatter plot^adding points
243*5c6c1daeSBarry Smith 
244*5c6c1daeSBarry Smith .seealso: PetscDrawSPAddPoint()
245*5c6c1daeSBarry Smith @*/
246*5c6c1daeSBarry Smith PetscErrorCode  PetscDrawSPAddPoints(PetscDrawSP sp,int n,PetscReal **xx,PetscReal **yy)
247*5c6c1daeSBarry Smith {
248*5c6c1daeSBarry Smith   PetscErrorCode ierr;
249*5c6c1daeSBarry Smith   PetscInt       i,j,k;
250*5c6c1daeSBarry Smith   PetscReal      *x,*y;
251*5c6c1daeSBarry Smith 
252*5c6c1daeSBarry Smith   PetscFunctionBegin;
253*5c6c1daeSBarry Smith   if (sp && ((PetscObject)sp)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
254*5c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp,PETSC_DRAWSP_CLASSID,1);
255*5c6c1daeSBarry Smith 
256*5c6c1daeSBarry Smith   if (sp->loc+n*sp->dim >= sp->len) { /* allocate more space */
257*5c6c1daeSBarry Smith     PetscReal *tmpx,*tmpy;
258*5c6c1daeSBarry Smith     PetscInt  chunk = CHUNCKSIZE;
259*5c6c1daeSBarry Smith     if (n > chunk) chunk = n;
260*5c6c1daeSBarry Smith     ierr = PetscMalloc2(sp->len+sp->dim*chunk,PetscReal,&tmpx,sp->len+sp->dim*chunk,PetscReal,&tmpy);CHKERRQ(ierr);
261*5c6c1daeSBarry Smith     ierr = PetscLogObjectMemory(sp,2*sp->dim*CHUNCKSIZE*sizeof(PetscReal));CHKERRQ(ierr);
262*5c6c1daeSBarry Smith     ierr = PetscMemcpy(tmpx,sp->x,sp->len*sizeof(PetscReal));CHKERRQ(ierr);
263*5c6c1daeSBarry Smith     ierr = PetscMemcpy(tmpy,sp->y,sp->len*sizeof(PetscReal));CHKERRQ(ierr);
264*5c6c1daeSBarry Smith     ierr = PetscFree2(sp->x,sp->y);CHKERRQ(ierr);
265*5c6c1daeSBarry Smith     sp->x    = tmpx;
266*5c6c1daeSBarry Smith     sp->y    = tmpy;
267*5c6c1daeSBarry Smith     sp->len += sp->dim*CHUNCKSIZE;
268*5c6c1daeSBarry Smith   }
269*5c6c1daeSBarry Smith   for (j=0; j<sp->dim; j++) {
270*5c6c1daeSBarry Smith     x = xx[j]; y = yy[j];
271*5c6c1daeSBarry Smith     k = sp->loc + j;
272*5c6c1daeSBarry Smith     for (i=0; i<n; i++) {
273*5c6c1daeSBarry Smith       if (x[i] > sp->xmax) sp->xmax = x[i];
274*5c6c1daeSBarry Smith       if (x[i] < sp->xmin) sp->xmin = x[i];
275*5c6c1daeSBarry Smith       if (y[i] > sp->ymax) sp->ymax = y[i];
276*5c6c1daeSBarry Smith       if (y[i] < sp->ymin) sp->ymin = y[i];
277*5c6c1daeSBarry Smith 
278*5c6c1daeSBarry Smith       sp->x[k] = x[i];
279*5c6c1daeSBarry Smith       sp->y[k] = y[i];
280*5c6c1daeSBarry Smith       k += sp->dim;
281*5c6c1daeSBarry Smith     }
282*5c6c1daeSBarry Smith   }
283*5c6c1daeSBarry Smith   sp->loc   += n*sp->dim;
284*5c6c1daeSBarry Smith   sp->nopts += n;
285*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
286*5c6c1daeSBarry Smith }
287*5c6c1daeSBarry Smith 
288*5c6c1daeSBarry Smith #undef __FUNCT__
289*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSPDraw"
290*5c6c1daeSBarry Smith /*@
291*5c6c1daeSBarry Smith    PetscDrawSPDraw - Redraws a scatter plot.
292*5c6c1daeSBarry Smith 
293*5c6c1daeSBarry Smith    Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
294*5c6c1daeSBarry Smith 
295*5c6c1daeSBarry Smith    Input Parameter:
296*5c6c1daeSBarry Smith +  sp - the line graph context
297*5c6c1daeSBarry Smith -  clear - clear the window before drawing the new plot
298*5c6c1daeSBarry Smith 
299*5c6c1daeSBarry Smith    Level: intermediate
300*5c6c1daeSBarry Smith 
301*5c6c1daeSBarry Smith .seealso: PetscDrawLGDraw(), PetscDrawLGSPDraw()
302*5c6c1daeSBarry Smith 
303*5c6c1daeSBarry Smith @*/
304*5c6c1daeSBarry Smith PetscErrorCode  PetscDrawSPDraw(PetscDrawSP sp, PetscBool clear)
305*5c6c1daeSBarry Smith {
306*5c6c1daeSBarry Smith   PetscReal      xmin=sp->xmin,xmax=sp->xmax,ymin=sp->ymin,ymax=sp->ymax;
307*5c6c1daeSBarry Smith   PetscErrorCode ierr;
308*5c6c1daeSBarry Smith   PetscInt       i,j,dim = sp->dim,nopts = sp->nopts;
309*5c6c1daeSBarry Smith   PetscMPIInt    rank;
310*5c6c1daeSBarry Smith   PetscDraw      draw = sp->win;
311*5c6c1daeSBarry Smith 
312*5c6c1daeSBarry Smith   PetscFunctionBegin;
313*5c6c1daeSBarry Smith   if (sp && ((PetscObject)sp)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
314*5c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp,PETSC_DRAWSP_CLASSID,1);
315*5c6c1daeSBarry Smith 
316*5c6c1daeSBarry Smith   if (nopts < 1) PetscFunctionReturn(0);
317*5c6c1daeSBarry Smith   if (xmin > xmax || ymin > ymax) PetscFunctionReturn(0);
318*5c6c1daeSBarry Smith   if (clear) {
319*5c6c1daeSBarry Smith     ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr);
320*5c6c1daeSBarry Smith     ierr = PetscDrawClear(draw);CHKERRQ(ierr);
321*5c6c1daeSBarry Smith   }
322*5c6c1daeSBarry Smith   ierr = PetscDrawAxisSetLimits(sp->axis,xmin,xmax,ymin,ymax);CHKERRQ(ierr);
323*5c6c1daeSBarry Smith   ierr = PetscDrawAxisDraw(sp->axis);CHKERRQ(ierr);
324*5c6c1daeSBarry Smith 
325*5c6c1daeSBarry Smith   ierr = MPI_Comm_rank(((PetscObject)sp)->comm,&rank);CHKERRQ(ierr);
326*5c6c1daeSBarry Smith   if (!rank) {
327*5c6c1daeSBarry Smith     for (i=0; i<dim; i++) {
328*5c6c1daeSBarry Smith       for (j=0; j<nopts; j++) {
329*5c6c1daeSBarry Smith 	ierr = PetscDrawPoint(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED);CHKERRQ(ierr);
330*5c6c1daeSBarry Smith       }
331*5c6c1daeSBarry Smith     }
332*5c6c1daeSBarry Smith   }
333*5c6c1daeSBarry Smith   ierr = PetscDrawFlush(sp->win);CHKERRQ(ierr);
334*5c6c1daeSBarry Smith   ierr = PetscDrawPause(sp->win);CHKERRQ(ierr);
335*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
336*5c6c1daeSBarry Smith }
337*5c6c1daeSBarry Smith 
338*5c6c1daeSBarry Smith #undef __FUNCT__
339*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSPSetLimits"
340*5c6c1daeSBarry Smith /*@
341*5c6c1daeSBarry Smith    PetscDrawSPSetLimits - Sets the axis limits for a line graph. If more
342*5c6c1daeSBarry Smith    points are added after this call, the limits will be adjusted to
343*5c6c1daeSBarry Smith    include those additional points.
344*5c6c1daeSBarry Smith 
345*5c6c1daeSBarry Smith    Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
346*5c6c1daeSBarry Smith 
347*5c6c1daeSBarry Smith    Input Parameters:
348*5c6c1daeSBarry Smith +  xsp - the line graph context
349*5c6c1daeSBarry Smith -  x_min,x_max,y_min,y_max - the limits
350*5c6c1daeSBarry Smith 
351*5c6c1daeSBarry Smith    Level: intermediate
352*5c6c1daeSBarry Smith 
353*5c6c1daeSBarry Smith    Concepts: scatter plot^setting axis
354*5c6c1daeSBarry Smith 
355*5c6c1daeSBarry Smith @*/
356*5c6c1daeSBarry Smith PetscErrorCode  PetscDrawSPSetLimits(PetscDrawSP sp,PetscReal x_min,PetscReal x_max,PetscReal y_min,PetscReal y_max)
357*5c6c1daeSBarry Smith {
358*5c6c1daeSBarry Smith   PetscFunctionBegin;
359*5c6c1daeSBarry Smith   if (sp && ((PetscObject)sp)->classid == PETSC_DRAW_CLASSID) PetscFunctionReturn(0);
360*5c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp,PETSC_DRAWSP_CLASSID,1);
361*5c6c1daeSBarry Smith   sp->xmin = x_min;
362*5c6c1daeSBarry Smith   sp->xmax = x_max;
363*5c6c1daeSBarry Smith   sp->ymin = y_min;
364*5c6c1daeSBarry Smith   sp->ymax = y_max;
365*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
366*5c6c1daeSBarry Smith }
367*5c6c1daeSBarry Smith 
368*5c6c1daeSBarry Smith #undef __FUNCT__
369*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSPGetAxis"
370*5c6c1daeSBarry Smith /*@C
371*5c6c1daeSBarry Smith    PetscDrawSPGetAxis - Gets the axis context associated with a line graph.
372*5c6c1daeSBarry Smith    This is useful if one wants to change some axis property, such as
373*5c6c1daeSBarry Smith    labels, color, etc. The axis context should not be destroyed by the
374*5c6c1daeSBarry Smith    application code.
375*5c6c1daeSBarry Smith 
376*5c6c1daeSBarry Smith    Not Collective (except PetscDrawAxis can only be used on processor 0 of PetscDrawSP)
377*5c6c1daeSBarry Smith 
378*5c6c1daeSBarry Smith    Input Parameter:
379*5c6c1daeSBarry Smith .  sp - the line graph context
380*5c6c1daeSBarry Smith 
381*5c6c1daeSBarry Smith    Output Parameter:
382*5c6c1daeSBarry Smith .  axis - the axis context
383*5c6c1daeSBarry Smith 
384*5c6c1daeSBarry Smith    Level: intermediate
385*5c6c1daeSBarry Smith 
386*5c6c1daeSBarry Smith @*/
387*5c6c1daeSBarry Smith PetscErrorCode  PetscDrawSPGetAxis(PetscDrawSP sp,PetscDrawAxis *axis)
388*5c6c1daeSBarry Smith {
389*5c6c1daeSBarry Smith   PetscFunctionBegin;
390*5c6c1daeSBarry Smith   if (sp && ((PetscObject)sp)->classid == PETSC_DRAW_CLASSID) {
391*5c6c1daeSBarry Smith     *axis = 0;
392*5c6c1daeSBarry Smith     PetscFunctionReturn(0);
393*5c6c1daeSBarry Smith   }
394*5c6c1daeSBarry Smith   PetscValidHeaderSpecific(sp,PETSC_DRAWSP_CLASSID,1);
395*5c6c1daeSBarry Smith   *axis = sp->axis;
396*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
397*5c6c1daeSBarry Smith }
398*5c6c1daeSBarry Smith 
399*5c6c1daeSBarry Smith #undef __FUNCT__
400*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSPGetDraw"
401*5c6c1daeSBarry Smith /*@C
402*5c6c1daeSBarry Smith    PetscDrawSPGetDraw - Gets the draw context associated with a line graph.
403*5c6c1daeSBarry Smith 
404*5c6c1daeSBarry Smith    Not Collective, PetscDraw is parallel if PetscDrawSP is parallel
405*5c6c1daeSBarry Smith 
406*5c6c1daeSBarry Smith    Input Parameter:
407*5c6c1daeSBarry Smith .  sp - the line graph context
408*5c6c1daeSBarry Smith 
409*5c6c1daeSBarry Smith    Output Parameter:
410*5c6c1daeSBarry Smith .  draw - the draw context
411*5c6c1daeSBarry Smith 
412*5c6c1daeSBarry Smith    Level: intermediate
413*5c6c1daeSBarry Smith 
414*5c6c1daeSBarry Smith @*/
415*5c6c1daeSBarry Smith PetscErrorCode  PetscDrawSPGetDraw(PetscDrawSP sp,PetscDraw *draw)
416*5c6c1daeSBarry Smith {
417*5c6c1daeSBarry Smith   PetscFunctionBegin;
418*5c6c1daeSBarry Smith   PetscValidHeader(sp,1);
419*5c6c1daeSBarry Smith   PetscValidPointer(draw,2);
420*5c6c1daeSBarry Smith   if (sp && ((PetscObject)sp)->classid == PETSC_DRAW_CLASSID) {
421*5c6c1daeSBarry Smith     *draw = (PetscDraw)sp;
422*5c6c1daeSBarry Smith   } else {
423*5c6c1daeSBarry Smith     *draw = sp->win;
424*5c6c1daeSBarry Smith   }
425*5c6c1daeSBarry Smith   PetscFunctionReturn(0);
426*5c6c1daeSBarry Smith }
427