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