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