xref: /petsc/src/sys/classes/draw/utils/lgc.c (revision 10699b917c2ca523f62b603029bfcc018e13d799)
1 
2 #include <petscviewer.h>
3 #include <../src/sys/classes/draw/utils/lgimpl.h>  /*I   "petscdraw.h"  I*/
4 PetscClassId PETSC_DRAWLG_CLASSID = 0;
5 
6 /*@
7    PetscDrawLGGetAxis - Gets the axis context associated with a line graph.
8    This is useful if one wants to change some axis property, such as
9    labels, color, etc. The axis context should not be destroyed by the
10    application code.
11 
12    Not Collective, if PetscDrawLG is parallel then PetscDrawAxis is parallel
13 
14    Input Parameter:
15 .  lg - the line graph context
16 
17    Output Parameter:
18 .  axis - the axis context
19 
20    Level: advanced
21 
22 .seealso: PetscDrawLGCreate(), PetscDrawAxis
23 
24 @*/
25 PetscErrorCode  PetscDrawLGGetAxis(PetscDrawLG lg,PetscDrawAxis *axis)
26 {
27   PetscFunctionBegin;
28   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
29   PetscValidPointer(axis,2);
30   *axis = lg->axis;
31   PetscFunctionReturn(0);
32 }
33 
34 /*@
35    PetscDrawLGGetDraw - Gets the draw context associated with a line graph.
36 
37    Not Collective, if PetscDrawLG is parallel then PetscDraw is parallel
38 
39    Input Parameter:
40 .  lg - the line graph context
41 
42    Output Parameter:
43 .  draw - the draw context
44 
45    Level: intermediate
46 
47 .seealso: PetscDrawLGCreate(), PetscDraw
48 @*/
49 PetscErrorCode  PetscDrawLGGetDraw(PetscDrawLG lg,PetscDraw *draw)
50 {
51   PetscFunctionBegin;
52   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
53   PetscValidPointer(draw,2);
54   *draw = lg->win;
55   PetscFunctionReturn(0);
56 }
57 
58 
59 /*@
60    PetscDrawLGSPDraw - Redraws a line graph.
61 
62    Collective on PetscDrawLG
63 
64    Input Parameter:
65 .  lg - the line graph context
66 
67    Level: intermediate
68 
69 .seealso: PetscDrawLGDraw(), PetscDrawSPDraw()
70 
71    Developer Notes:
72     This code cheats and uses the fact that the LG and SP structs are the same
73 
74 @*/
75 PetscErrorCode  PetscDrawLGSPDraw(PetscDrawLG lg,PetscDrawSP spin)
76 {
77   PetscDrawLG    sp = (PetscDrawLG)spin;
78   PetscReal      xmin,xmax,ymin,ymax;
79   PetscErrorCode ierr;
80   PetscBool      isnull;
81   PetscMPIInt    rank;
82   PetscDraw      draw;
83 
84   PetscFunctionBegin;
85   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
86   PetscValidHeaderSpecific(sp,PETSC_DRAWSP_CLASSID,2);
87   ierr = PetscDrawIsNull(lg->win,&isnull);CHKERRQ(ierr);
88   if (isnull) PetscFunctionReturn(0);
89   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)lg),&rank);CHKERRMPI(ierr);
90 
91   draw = lg->win;
92   ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr);
93   ierr = PetscDrawClear(draw);CHKERRQ(ierr);
94 
95   xmin = PetscMin(lg->xmin,sp->xmin); ymin = PetscMin(lg->ymin,sp->ymin);
96   xmax = PetscMax(lg->xmax,sp->xmax); ymax = PetscMax(lg->ymax,sp->ymax);
97   ierr = PetscDrawAxisSetLimits(lg->axis,xmin,xmax,ymin,ymax);CHKERRQ(ierr);
98   ierr = PetscDrawAxisDraw(lg->axis);CHKERRQ(ierr);
99 
100   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
101   if (!rank) {
102     int i,j,dim,nopts;
103     dim   = lg->dim;
104     nopts = lg->nopts;
105     for (i=0; i<dim; i++) {
106       for (j=1; j<nopts; j++) {
107         ierr = PetscDrawLine(draw,lg->x[(j-1)*dim+i],lg->y[(j-1)*dim+i],lg->x[j*dim+i],lg->y[j*dim+i],PETSC_DRAW_BLACK+i);CHKERRQ(ierr);
108         if (lg->use_markers) {
109           ierr = PetscDrawMarker(draw,lg->x[j*dim+i],lg->y[j*dim+i],PETSC_DRAW_RED);CHKERRQ(ierr);
110         }
111       }
112     }
113     dim   = sp->dim;
114     nopts = sp->nopts;
115     for (i=0; i<dim; i++) {
116       for (j=0; j<nopts; j++) {
117         ierr = PetscDrawMarker(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED);CHKERRQ(ierr);
118       }
119     }
120   }
121   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
122 
123   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
124   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
125   PetscFunctionReturn(0);
126 }
127 
128 
129 /*@
130     PetscDrawLGCreate - Creates a line graph data structure.
131 
132     Collective on PetscDraw
133 
134     Input Parameters:
135 +   draw - the window where the graph will be made.
136 -   dim - the number of curves which will be drawn
137 
138     Output Parameters:
139 .   outlg - the line graph context
140 
141     Level: intermediate
142 
143     Notes:
144     The MPI communicator that owns the PetscDraw owns this PetscDrawLG, but the calls to set options and add points are ignored on all processes except the
145            zeroth MPI process in the communicator. All MPI processes in the communicator must call PetscDrawLGDraw() to display the updated graph.
146 
147 .seealso:  PetscDrawLGDestroy(), PetscDrawLGAddPoint(), PetscDrawLGAddCommonPoint(), PetscDrawLGAddPoints(), PetscDrawLGDraw(), PetscDrawLGSave(),
148            PetscDrawLGView(), PetscDrawLGReset(), PetscDrawLGSetDimension(), PetscDrawLGGetDimension(), PetscDrawLGSetLegend(), PetscDrawLGGetAxis(),
149            PetscDrawLGGetDraw(), PetscDrawLGSetUseMarkers(), PetscDrawLGSetLimits(), PetscDrawLGSetColors(), PetscDrawLGSetOptionsPrefix(), PetscDrawLGSetFromOptions()
150 @*/
151 PetscErrorCode  PetscDrawLGCreate(PetscDraw draw,PetscInt dim,PetscDrawLG *outlg)
152 {
153   PetscDrawLG    lg;
154   PetscErrorCode ierr;
155 
156   PetscFunctionBegin;
157   PetscValidHeaderSpecific(draw,PETSC_DRAW_CLASSID,1);
158   PetscValidLogicalCollectiveInt(draw,dim,2);
159   PetscValidPointer(outlg,3);
160 
161   ierr = PetscHeaderCreate(lg,PETSC_DRAWLG_CLASSID,"DrawLG","Line Graph","Draw",PetscObjectComm((PetscObject)draw),PetscDrawLGDestroy,NULL);CHKERRQ(ierr);
162   ierr = PetscLogObjectParent((PetscObject)draw,(PetscObject)lg);CHKERRQ(ierr);
163   ierr = PetscDrawLGSetOptionsPrefix(lg,((PetscObject)draw)->prefix);CHKERRQ(ierr);
164 
165   ierr = PetscObjectReference((PetscObject)draw);CHKERRQ(ierr);
166   lg->win = draw;
167 
168   lg->view    = NULL;
169   lg->destroy = NULL;
170   lg->nopts   = 0;
171   lg->dim     = dim;
172   lg->xmin    = 1.e20;
173   lg->ymin    = 1.e20;
174   lg->xmax    = -1.e20;
175   lg->ymax    = -1.e20;
176 
177   ierr = PetscMalloc2(dim*CHUNCKSIZE,&lg->x,dim*CHUNCKSIZE,&lg->y);CHKERRQ(ierr);
178   ierr = PetscLogObjectMemory((PetscObject)lg,2*dim*CHUNCKSIZE*sizeof(PetscReal));CHKERRQ(ierr);
179 
180   lg->len         = dim*CHUNCKSIZE;
181   lg->loc         = 0;
182   lg->use_markers = PETSC_FALSE;
183 
184   ierr = PetscDrawAxisCreate(draw,&lg->axis);CHKERRQ(ierr);
185   ierr = PetscLogObjectParent((PetscObject)lg,(PetscObject)lg->axis);CHKERRQ(ierr);
186 
187   *outlg = lg;
188   PetscFunctionReturn(0);
189 }
190 
191 /*@
192    PetscDrawLGSetColors - Sets the color of each line graph drawn
193 
194    Logically Collective on PetscDrawLG
195 
196    Input Parameter:
197 +  lg - the line graph context.
198 -  colors - the colors
199 
200    Level: intermediate
201 
202 .seealso: PetscDrawLGCreate()
203 
204 @*/
205 PetscErrorCode  PetscDrawLGSetColors(PetscDrawLG lg,const int colors[])
206 {
207   PetscErrorCode ierr;
208 
209   PetscFunctionBegin;
210   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
211   if (lg->dim) PetscValidIntPointer(colors,2);
212 
213   ierr = PetscFree(lg->colors);CHKERRQ(ierr);
214   ierr = PetscMalloc1(lg->dim,&lg->colors);CHKERRQ(ierr);
215   ierr = PetscArraycpy(lg->colors,colors,lg->dim);CHKERRQ(ierr);
216   PetscFunctionReturn(0);
217 }
218 
219 /*@C
220    PetscDrawLGSetLegend - sets the names of each curve plotted
221 
222    Logically Collective on PetscDrawLG
223 
224    Input Parameter:
225 +  lg - the line graph context.
226 -  names - the names for each curve
227 
228    Level: intermediate
229 
230    Notes:
231     Call PetscDrawLGGetAxis() and then change properties of the PetscDrawAxis for detailed control of the plot
232 
233 .seealso: PetscDrawLGGetAxis(), PetscDrawAxis, PetscDrawAxisSetColors(), PetscDrawAxisSetLabels(), PetscDrawAxisSetHoldLimits()
234 
235 @*/
236 PetscErrorCode  PetscDrawLGSetLegend(PetscDrawLG lg,const char *const *names)
237 {
238   PetscErrorCode ierr;
239   PetscInt       i;
240 
241   PetscFunctionBegin;
242   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
243   if (names) PetscValidPointer(names,2);
244 
245   if (lg->legend) {
246     for (i=0; i<lg->dim; i++) {
247       ierr = PetscFree(lg->legend[i]);CHKERRQ(ierr);
248     }
249     ierr = PetscFree(lg->legend);CHKERRQ(ierr);
250   }
251   if (names) {
252     ierr = PetscMalloc1(lg->dim,&lg->legend);CHKERRQ(ierr);
253     for (i=0; i<lg->dim; i++) {
254       ierr = PetscStrallocpy(names[i],&lg->legend[i]);CHKERRQ(ierr);
255     }
256   }
257   PetscFunctionReturn(0);
258 }
259 
260 /*@
261    PetscDrawLGGetDimension - Change the number of lines that are to be drawn.
262 
263    Not Collective
264 
265    Input Parameter:
266 .  lg - the line graph context.
267 
268    Output Parameter:
269 .  dim - the number of curves.
270 
271    Level: intermediate
272 
273 .seealso: PetscDrawLGCreate(), PetscDrawLGSetDimension()
274 
275 @*/
276 PetscErrorCode  PetscDrawLGGetDimension(PetscDrawLG lg,PetscInt *dim)
277 {
278   PetscFunctionBegin;
279   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
280   PetscValidIntPointer(dim,2);
281   *dim = lg->dim;
282   PetscFunctionReturn(0);
283 }
284 
285 /*@
286    PetscDrawLGSetDimension - Change the number of lines that are to be drawn.
287 
288    Logically Collective on PetscDrawLG
289 
290    Input Parameter:
291 +  lg - the line graph context.
292 -  dim - the number of curves.
293 
294    Level: intermediate
295 
296 .seealso: PetscDrawLGCreate(), PetscDrawLGGetDimension()
297 @*/
298 PetscErrorCode  PetscDrawLGSetDimension(PetscDrawLG lg,PetscInt dim)
299 {
300   PetscErrorCode ierr;
301   PetscInt       i;
302 
303   PetscFunctionBegin;
304   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
305   PetscValidLogicalCollectiveInt(lg,dim,2);
306   if (lg->dim == dim) PetscFunctionReturn(0);
307 
308   ierr = PetscFree2(lg->x,lg->y);CHKERRQ(ierr);
309   if (lg->legend) {
310     for (i=0; i<lg->dim; i++) {
311       ierr = PetscFree(lg->legend[i]);CHKERRQ(ierr);
312     }
313     ierr = PetscFree(lg->legend);CHKERRQ(ierr);
314   }
315   ierr    = PetscFree(lg->colors);CHKERRQ(ierr);
316   lg->dim = dim;
317   ierr    = PetscMalloc2(dim*CHUNCKSIZE,&lg->x,dim*CHUNCKSIZE,&lg->y);CHKERRQ(ierr);
318   ierr    = PetscLogObjectMemory((PetscObject)lg,2*dim*CHUNCKSIZE*sizeof(PetscReal));CHKERRQ(ierr);
319   lg->len = dim*CHUNCKSIZE;
320   PetscFunctionReturn(0);
321 }
322 
323 
324 /*@
325    PetscDrawLGSetLimits - Sets the axis limits for a line graph. If more
326    points are added after this call, the limits will be adjusted to
327    include those additional points.
328 
329    Logically Collective on PetscDrawLG
330 
331    Input Parameters:
332 +  xlg - the line graph context
333 -  x_min,x_max,y_min,y_max - the limits
334 
335    Level: intermediate
336 
337 .seealso: PetscDrawLGCreate()
338 
339 @*/
340 PetscErrorCode  PetscDrawLGSetLimits(PetscDrawLG lg,PetscReal x_min,PetscReal x_max,PetscReal y_min,PetscReal y_max)
341 {
342   PetscFunctionBegin;
343   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
344 
345   (lg)->xmin = x_min;
346   (lg)->xmax = x_max;
347   (lg)->ymin = y_min;
348   (lg)->ymax = y_max;
349   PetscFunctionReturn(0);
350 }
351 
352 /*@
353    PetscDrawLGReset - Clears line graph to allow for reuse with new data.
354 
355    Logically Collective on PetscDrawLG
356 
357    Input Parameter:
358 .  lg - the line graph context.
359 
360    Level: intermediate
361 
362 .seealso: PetscDrawLGCreate()
363 @*/
364 PetscErrorCode  PetscDrawLGReset(PetscDrawLG lg)
365 {
366   PetscFunctionBegin;
367   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
368   lg->xmin  = 1.e20;
369   lg->ymin  = 1.e20;
370   lg->xmax  = -1.e20;
371   lg->ymax  = -1.e20;
372   lg->loc   = 0;
373   lg->nopts = 0;
374   PetscFunctionReturn(0);
375 }
376 
377 /*@
378    PetscDrawLGDestroy - Frees all space taken up by line graph data structure.
379 
380    Collective on PetscDrawLG
381 
382    Input Parameter:
383 .  lg - the line graph context
384 
385    Level: intermediate
386 
387 .seealso:  PetscDrawLGCreate()
388 @*/
389 PetscErrorCode  PetscDrawLGDestroy(PetscDrawLG *lg)
390 {
391   PetscErrorCode ierr;
392   PetscInt       i;
393 
394   PetscFunctionBegin;
395   if (!*lg) PetscFunctionReturn(0);
396   PetscValidHeaderSpecific(*lg,PETSC_DRAWLG_CLASSID,1);
397   if (--((PetscObject)(*lg))->refct > 0) {*lg = NULL; PetscFunctionReturn(0);}
398 
399   if ((*lg)->legend) {
400     for (i=0; i<(*lg)->dim; i++) {
401       ierr = PetscFree((*lg)->legend[i]);CHKERRQ(ierr);
402     }
403     ierr = PetscFree((*lg)->legend);CHKERRQ(ierr);
404   }
405   ierr = PetscFree((*lg)->colors);CHKERRQ(ierr);
406   ierr = PetscFree2((*lg)->x,(*lg)->y);CHKERRQ(ierr);
407   ierr = PetscDrawAxisDestroy(&(*lg)->axis);CHKERRQ(ierr);
408   ierr = PetscDrawDestroy(&(*lg)->win);CHKERRQ(ierr);
409   ierr = PetscHeaderDestroy(lg);CHKERRQ(ierr);
410   PetscFunctionReturn(0);
411 }
412 /*@
413    PetscDrawLGSetUseMarkers - Causes LG to draw a marker for each data-point.
414 
415    Logically Collective on PetscDrawLG
416 
417    Input Parameters:
418 +  lg - the linegraph context
419 -  flg - should mark each data point
420 
421    Options Database:
422 .  -lg_use_markers  <true,false> - true means the graphPetscDrawLG draws a marker for each point
423 
424    Level: intermediate
425 
426 .seealso: PetscDrawLGCreate()
427 @*/
428 PetscErrorCode  PetscDrawLGSetUseMarkers(PetscDrawLG lg,PetscBool flg)
429 {
430   PetscFunctionBegin;
431   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
432   PetscValidLogicalCollectiveBool(lg,flg,2);
433   lg->use_markers = flg;
434   PetscFunctionReturn(0);
435 }
436 
437 /*@
438    PetscDrawLGDraw - Redraws a line graph.
439 
440    Collective on PetscDrawLG
441 
442    Input Parameter:
443 .  lg - the line graph context
444 
445    Level: intermediate
446 
447 .seealso: PetscDrawSPDraw(), PetscDrawLGSPDraw(), PetscDrawLGReset()
448 @*/
449 PetscErrorCode  PetscDrawLGDraw(PetscDrawLG lg)
450 {
451   PetscReal      xmin,xmax,ymin,ymax;
452   PetscErrorCode ierr;
453   PetscMPIInt    rank;
454   PetscDraw      draw;
455   PetscBool      isnull;
456 
457   PetscFunctionBegin;
458   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
459   ierr = PetscDrawIsNull(lg->win,&isnull);CHKERRQ(ierr);
460   if (isnull) PetscFunctionReturn(0);
461   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)lg),&rank);CHKERRMPI(ierr);
462 
463   draw = lg->win;
464   ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr);
465   ierr = PetscDrawClear(draw);CHKERRQ(ierr);
466 
467   xmin = lg->xmin; xmax = lg->xmax; ymin = lg->ymin; ymax = lg->ymax;
468   ierr = PetscDrawAxisSetLimits(lg->axis,xmin,xmax,ymin,ymax);CHKERRQ(ierr);
469   ierr = PetscDrawAxisDraw(lg->axis);CHKERRQ(ierr);
470 
471   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
472   if (!rank) {
473     int i,j,dim=lg->dim,nopts=lg->nopts,cl;
474     for (i=0; i<dim; i++) {
475       for (j=1; j<nopts; j++) {
476         cl   = lg->colors ? lg->colors[i] : ((PETSC_DRAW_BLACK + i) % PETSC_DRAW_MAXCOLOR);
477         ierr = PetscDrawLine(draw,lg->x[(j-1)*dim+i],lg->y[(j-1)*dim+i],lg->x[j*dim+i],lg->y[j*dim+i],cl);CHKERRQ(ierr);
478         if (lg->use_markers) {ierr = PetscDrawMarker(draw,lg->x[j*dim+i],lg->y[j*dim+i],cl);CHKERRQ(ierr);}
479       }
480     }
481   }
482   if (!rank && lg->legend) {
483     int       i,dim=lg->dim,cl;
484     PetscReal xl,yl,xr,yr,tw,th;
485     size_t    slen,len=0;
486     ierr = PetscDrawAxisGetLimits(lg->axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr);
487     ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
488     for (i=0; i<dim; i++) {
489       ierr = PetscStrlen(lg->legend[i],&slen);CHKERRQ(ierr);
490       len = PetscMax(len,slen);
491     }
492     xr = xr - 1.5*tw; xl = xr - (len + 7)*tw;
493     yr = yr - 1.0*th; yl = yr - (dim + 1)*th;
494     ierr = PetscDrawLine(draw,xl,yl,xr,yl,PETSC_DRAW_BLACK);CHKERRQ(ierr);
495     ierr = PetscDrawLine(draw,xr,yl,xr,yr,PETSC_DRAW_BLACK);CHKERRQ(ierr);
496     ierr = PetscDrawLine(draw,xr,yr,xl,yr,PETSC_DRAW_BLACK);CHKERRQ(ierr);
497     ierr = PetscDrawLine(draw,xl,yr,xl,yl,PETSC_DRAW_BLACK);CHKERRQ(ierr);
498     for  (i=0; i<dim; i++) {
499       cl   = lg->colors ? lg->colors[i] : (PETSC_DRAW_BLACK + i);
500       ierr = PetscDrawLine(draw,xl + 1*tw,yr - (i + 1)*th,xl + 5*tw,yr - (i + 1)*th,cl);CHKERRQ(ierr);
501       ierr = PetscDrawString(draw,xl + 6*tw,yr - (i + 1.5)*th,PETSC_DRAW_BLACK,lg->legend[i]);CHKERRQ(ierr);
502     }
503   }
504   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
505 
506   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
507   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
508   PetscFunctionReturn(0);
509 }
510 
511 /*@
512   PetscDrawLGSave - Saves a drawn image
513 
514   Collective on PetscDrawLG
515 
516   Input Parameter:
517 . lg - The line graph context
518 
519   Level: intermediate
520 
521 .seealso:  PetscDrawLGCreate(), PetscDrawLGGetDraw(), PetscDrawSetSave(), PetscDrawSave()
522 @*/
523 PetscErrorCode  PetscDrawLGSave(PetscDrawLG lg)
524 {
525   PetscErrorCode ierr;
526 
527   PetscFunctionBegin;
528   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
529   ierr = PetscDrawSave(lg->win);CHKERRQ(ierr);
530   PetscFunctionReturn(0);
531 }
532 
533 /*@
534   PetscDrawLGView - Prints a line graph.
535 
536   Collective on PetscDrawLG
537 
538   Input Parameter:
539 . lg - the line graph context
540 
541   Level: beginner
542 
543 .seealso: PetscDrawLGCreate()
544 
545 @*/
546 PetscErrorCode  PetscDrawLGView(PetscDrawLG lg,PetscViewer viewer)
547 {
548   PetscReal      xmin=lg->xmin, xmax=lg->xmax, ymin=lg->ymin, ymax=lg->ymax;
549   PetscInt       i, j, dim = lg->dim, nopts = lg->nopts;
550   PetscErrorCode ierr;
551 
552   PetscFunctionBegin;
553   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
554 
555   if (nopts < 1)                  PetscFunctionReturn(0);
556   if (xmin > xmax || ymin > ymax) PetscFunctionReturn(0);
557 
558   if (!viewer){
559     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg),&viewer);CHKERRQ(ierr);
560   }
561   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)lg,viewer);CHKERRQ(ierr);
562   for (i = 0; i < dim; i++) {
563     ierr = PetscViewerASCIIPrintf(viewer, "Line %D>\n", i);CHKERRQ(ierr);
564     for (j = 0; j < nopts; j++) {
565       ierr = PetscViewerASCIIPrintf(viewer, "  X: %g Y: %g\n", (double)lg->x[j*dim+i], (double)lg->y[j*dim+i]);CHKERRQ(ierr);
566     }
567   }
568   PetscFunctionReturn(0);
569 }
570 
571 /*@C
572    PetscDrawLGSetOptionsPrefix - Sets the prefix used for searching for all
573    PetscDrawLG options in the database.
574 
575    Logically Collective on PetscDrawLG
576 
577    Input Parameter:
578 +  lg - the line graph context
579 -  prefix - the prefix to prepend to all option names
580 
581    Level: advanced
582 
583 .seealso: PetscDrawLGSetFromOptions(), PetscDrawLGCreate()
584 @*/
585 PetscErrorCode  PetscDrawLGSetOptionsPrefix(PetscDrawLG lg,const char prefix[])
586 {
587   PetscErrorCode ierr;
588 
589   PetscFunctionBegin;
590   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
591   ierr = PetscObjectSetOptionsPrefix((PetscObject)lg,prefix);CHKERRQ(ierr);
592   PetscFunctionReturn(0);
593 }
594 
595 /*@
596     PetscDrawLGSetFromOptions - Sets options related to the PetscDrawLG
597 
598     Collective on PetscDrawLG
599 
600     Options Database:
601 
602     Level: intermediate
603 
604 .seealso:  PetscDrawLGDestroy(), PetscDrawLGCreate()
605 @*/
606 PetscErrorCode  PetscDrawLGSetFromOptions(PetscDrawLG lg)
607 {
608   PetscErrorCode      ierr;
609   PetscBool           usemarkers,set;
610   PetscDrawMarkerType markertype;
611 
612   PetscFunctionBegin;
613   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
614 
615   ierr = PetscDrawGetMarkerType(lg->win,&markertype);CHKERRQ(ierr);
616   ierr = PetscOptionsGetEnum(((PetscObject)lg)->options,((PetscObject)lg)->prefix,"-lg_marker_type",PetscDrawMarkerTypes,(PetscEnum*)&markertype,&set);CHKERRQ(ierr);
617   if (set) {
618     ierr = PetscDrawLGSetUseMarkers(lg,PETSC_TRUE);CHKERRQ(ierr);
619     ierr = PetscDrawSetMarkerType(lg->win,markertype);CHKERRQ(ierr);
620   }
621   usemarkers = lg->use_markers;
622   ierr = PetscOptionsGetBool(((PetscObject)lg)->options,((PetscObject)lg)->prefix,"-lg_use_markers",&usemarkers,&set);CHKERRQ(ierr);
623   if (set) {ierr = PetscDrawLGSetUseMarkers(lg,usemarkers);CHKERRQ(ierr);}
624   PetscFunctionReturn(0);
625 }
626