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