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