xref: /petsc/src/sys/classes/draw/utils/lgc.c (revision 95dccacacae8a8fc0b691f9b4fba69a249b61188)
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   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
29   PetscValidPointer(axis,2);
30   *axis = lg->axis;
31   PetscFunctionReturn(0);
32 }
33 
34 #undef __FUNCT__
35 #define __FUNCT__ "PetscDrawLGGetDraw"
36 /*@
37    PetscDrawLGGetDraw - Gets the draw context associated with a line graph.
38 
39    Not Collective, if PetscDrawLG is parallel then PetscDraw is parallel
40 
41    Input Parameter:
42 .  lg - the line graph context
43 
44    Output Parameter:
45 .  draw - the draw context
46 
47    Level: intermediate
48 
49 @*/
50 PetscErrorCode  PetscDrawLGGetDraw(PetscDrawLG lg,PetscDraw *draw)
51 {
52   PetscFunctionBegin;
53   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
54   PetscValidPointer(draw,2);
55   *draw = lg->win;
56   PetscFunctionReturn(0);
57 }
58 
59 
60 #undef __FUNCT__
61 #define __FUNCT__ "PetscDrawLGSPDraw"
62 /*@
63    PetscDrawLGSPDraw - Redraws a line graph.
64 
65    Collective on PetscDrawLG
66 
67    Input Parameter:
68 .  lg - the line graph context
69 
70    Level: intermediate
71 
72 .seealso: PetscDrawLGDraw(), PetscDrawSPDraw()
73 
74    Developer Notes: This code cheats and uses the fact that the LG and SP structs are the same
75 
76 @*/
77 PetscErrorCode  PetscDrawLGSPDraw(PetscDrawLG lg,PetscDrawSP spin)
78 {
79   PetscDrawLG    sp = (PetscDrawLG)spin;
80   PetscReal      xmin,xmax,ymin,ymax;
81   PetscErrorCode ierr;
82   PetscBool      isnull;
83   PetscMPIInt    rank;
84   PetscDraw      draw;
85 
86   PetscFunctionBegin;
87   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
88   PetscValidHeaderSpecific(sp,PETSC_DRAWSP_CLASSID,2);
89   ierr = PetscDrawIsNull(lg->win,&isnull);CHKERRQ(ierr);
90   if (isnull) PetscFunctionReturn(0);
91   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)lg),&rank);CHKERRQ(ierr);
92 
93   draw = lg->win;
94   ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr);
95   ierr = PetscDrawClear(draw);CHKERRQ(ierr);
96 
97   xmin = PetscMin(lg->xmin,sp->xmin); ymin = PetscMin(lg->ymin,sp->ymin);
98   xmax = PetscMax(lg->xmax,sp->xmax); ymax = PetscMax(lg->ymax,sp->ymax);
99   ierr = PetscDrawAxisSetLimits(lg->axis,xmin,xmax,ymin,ymax);CHKERRQ(ierr);
100   ierr = PetscDrawAxisDraw(lg->axis);CHKERRQ(ierr);
101 
102   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
103   if (!rank) {
104     int i,j,dim,nopts;
105     dim   = lg->dim;
106     nopts = lg->nopts;
107     for (i=0; i<dim; i++) {
108       for (j=1; j<nopts; j++) {
109         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);
110         if (lg->use_markers) {
111           ierr = PetscDrawMarker(draw,lg->x[j*dim+i],lg->y[j*dim+i],PETSC_DRAW_RED);CHKERRQ(ierr);
112         }
113       }
114     }
115     dim   = sp->dim;
116     nopts = sp->nopts;
117     for (i=0; i<dim; i++) {
118       for (j=0; j<nopts; j++) {
119         ierr = PetscDrawMarker(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED);CHKERRQ(ierr);
120       }
121     }
122   }
123   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
124 
125   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
126   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
127   PetscFunctionReturn(0);
128 }
129 
130 
131 #undef __FUNCT__
132 #define __FUNCT__ "PetscDrawLGCreate"
133 /*@
134     PetscDrawLGCreate - Creates a line graph data structure.
135 
136     Collective on PetscDraw
137 
138     Input Parameters:
139 +   draw - the window where the graph will be made.
140 -   dim - the number of curves which will be drawn
141 
142     Output Parameters:
143 .   outlg - the line graph context
144 
145     Level: intermediate
146 
147     Concepts: line graph^creating
148 
149 .seealso:  PetscDrawLGDestroy()
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 #undef __FUNCT__
192 #define __FUNCT__ "PetscDrawLGSetColors"
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 @*/
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 #undef __FUNCT__
222 #undef __FUNCT__
223 #define __FUNCT__ "PetscDrawLGSetLegend"
224 /*@C
225    PetscDrawLGSetLegend - sets the names of each curve plotted
226 
227    Logically Collective on PetscDrawLG
228 
229    Input Parameter:
230 +  lg - the line graph context.
231 -  names - the names for each curve
232 
233    Level: intermediate
234 
235    Concepts: line graph^setting number of lines
236 
237 @*/
238 PetscErrorCode  PetscDrawLGSetLegend(PetscDrawLG lg,const char *const *names)
239 {
240   PetscErrorCode ierr;
241   PetscInt       i;
242 
243   PetscFunctionBegin;
244   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
245   if (names) PetscValidPointer(names,2);
246 
247   if (lg->legend) {
248     for (i=0; i<lg->dim; i++) {
249       ierr = PetscFree(lg->legend[i]);CHKERRQ(ierr);
250     }
251     ierr = PetscFree(lg->legend);CHKERRQ(ierr);
252   }
253   if (names) {
254     ierr = PetscMalloc1(lg->dim,&lg->legend);CHKERRQ(ierr);
255     for (i=0; i<lg->dim; i++) {
256       ierr = PetscStrallocpy(names[i],&lg->legend[i]);CHKERRQ(ierr);
257     }
258   }
259   PetscFunctionReturn(0);
260 }
261 
262 #undef __FUNCT__
263 #define __FUNCT__ "PetscDrawLGGetDimension"
264 /*@
265    PetscDrawLGGetDimension - Change the number of lines that are to be drawn.
266 
267    Not Collective
268 
269    Input Parameter:
270 .  lg - the line graph context.
271 
272    Output Parameter:
273 .  dim - the number of curves.
274 
275    Level: intermediate
276 
277    Concepts: line graph^setting number of lines
278 
279 @*/
280 PetscErrorCode  PetscDrawLGGetDimension(PetscDrawLG lg,PetscInt *dim)
281 {
282   PetscFunctionBegin;
283   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
284   PetscValidIntPointer(dim,2);
285   *dim = lg->dim;
286   PetscFunctionReturn(0);
287 }
288 
289 #undef __FUNCT__
290 #define __FUNCT__ "PetscDrawLGSetDimension"
291 /*@
292    PetscDrawLGSetDimension - Change the number of lines that are to be drawn.
293 
294    Logically Collective on PetscDrawLG
295 
296    Input Parameter:
297 +  lg - the line graph context.
298 -  dim - the number of curves.
299 
300    Level: intermediate
301 
302    Concepts: line graph^setting number of lines
303 
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 #undef __FUNCT__
332 #define __FUNCT__ "PetscDrawLGSetLimits"
333 /*@
334    PetscDrawLGSetLimits - Sets the axis limits for a line graph. If more
335    points are added after this call, the limits will be adjusted to
336    include those additional points.
337 
338    Logically Collective on PetscDrawLG
339 
340    Input Parameters:
341 +  xlg - the line graph context
342 -  x_min,x_max,y_min,y_max - the limits
343 
344    Level: intermediate
345 
346    Concepts: line graph^setting axis
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 #undef __FUNCT__
362 #define __FUNCT__ "PetscDrawLGReset"
363 /*@
364    PetscDrawLGReset - Clears line graph to allow for reuse with new data.
365 
366    Logically Collective on PetscDrawLG
367 
368    Input Parameter:
369 .  lg - the line graph context.
370 
371    Level: intermediate
372 
373    Concepts: line graph^restarting
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 #undef __FUNCT__
390 #define __FUNCT__ "PetscDrawLGDestroy"
391 /*@
392    PetscDrawLGDestroy - Frees all space taken up by line graph data structure.
393 
394    Collective on PetscDrawLG
395 
396    Input Parameter:
397 .  lg - the line graph context
398 
399    Level: intermediate
400 
401 .seealso:  PetscDrawLGCreate()
402 @*/
403 PetscErrorCode  PetscDrawLGDestroy(PetscDrawLG *lg)
404 {
405   PetscErrorCode ierr;
406   PetscInt       i;
407 
408   PetscFunctionBegin;
409   if (!*lg) PetscFunctionReturn(0);
410   PetscValidHeaderSpecific(*lg,PETSC_DRAWLG_CLASSID,1);
411   if (--((PetscObject)(*lg))->refct > 0) {*lg = NULL; PetscFunctionReturn(0);}
412 
413   if ((*lg)->legend) {
414     for (i=0; i<(*lg)->dim; i++) {
415       ierr = PetscFree((*lg)->legend[i]);CHKERRQ(ierr);
416     }
417     ierr = PetscFree((*lg)->legend);CHKERRQ(ierr);
418   }
419   ierr = PetscFree((*lg)->colors);CHKERRQ(ierr);
420   ierr = PetscFree2((*lg)->x,(*lg)->y);CHKERRQ(ierr);
421   ierr = PetscDrawAxisDestroy(&(*lg)->axis);CHKERRQ(ierr);
422   ierr = PetscDrawDestroy(&(*lg)->win);CHKERRQ(ierr);
423   ierr = PetscHeaderDestroy(lg);CHKERRQ(ierr);
424   PetscFunctionReturn(0);
425 }
426 #undef __FUNCT__
427 #define __FUNCT__ "PetscDrawLGSetUseMarkers"
428 /*@
429    PetscDrawLGSetUseMarkers - Causes LG to draw a marker for each data-point.
430 
431    Logically Collective on PetscDrawLG
432 
433    Input Parameters:
434 +  lg - the linegraph context
435 -  flg - should mark each data point
436 
437    Options Database:
438 .  -lg_use_markers  <true,false>
439 
440    Level: intermediate
441 
442    Concepts: line graph^showing points
443 
444 @*/
445 PetscErrorCode  PetscDrawLGSetUseMarkers(PetscDrawLG lg,PetscBool flg)
446 {
447   PetscFunctionBegin;
448   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
449   PetscValidLogicalCollectiveBool(lg,flg,2);
450   lg->use_markers = flg;
451   PetscFunctionReturn(0);
452 }
453 
454 #undef __FUNCT__
455 #define __FUNCT__ "PetscDrawLGDraw"
456 /*@
457    PetscDrawLGDraw - Redraws a line graph.
458 
459    Collective on PetscDrawLG
460 
461    Input Parameter:
462 .  lg - the line graph context
463 
464    Level: intermediate
465 
466 .seealso: PetscDrawSPDraw(), PetscDrawLGSPDraw()
467 
468 @*/
469 PetscErrorCode  PetscDrawLGDraw(PetscDrawLG lg)
470 {
471   PetscReal      xmin,xmax,ymin,ymax;
472   PetscErrorCode ierr;
473   PetscMPIInt    rank;
474   PetscDraw      draw;
475   PetscBool      isnull;
476 
477   PetscFunctionBegin;
478   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
479   ierr = PetscDrawIsNull(lg->win,&isnull);CHKERRQ(ierr);
480   if (isnull) PetscFunctionReturn(0);
481   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)lg),&rank);CHKERRQ(ierr);
482 
483   draw = lg->win;
484   ierr = PetscDrawCheckResizedWindow(draw);CHKERRQ(ierr);
485   ierr = PetscDrawClear(draw);CHKERRQ(ierr);
486 
487   xmin = lg->xmin; xmax = lg->xmax; ymin = lg->ymin; ymax = lg->ymax;
488   ierr = PetscDrawAxisSetLimits(lg->axis,xmin,xmax,ymin,ymax);CHKERRQ(ierr);
489   ierr = PetscDrawAxisDraw(lg->axis);CHKERRQ(ierr);
490 
491   ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr);
492   if (!rank) {
493     int i,j,dim=lg->dim,nopts=lg->nopts,cl;
494     for (i=0; i<dim; i++) {
495       for (j=1; j<nopts; j++) {
496         cl   = lg->colors ? lg->colors[i] : (PETSC_DRAW_BLACK + i);
497         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);
498         if (lg->use_markers) {ierr = PetscDrawMarker(draw,lg->x[j*dim+i],lg->y[j*dim+i],cl);CHKERRQ(ierr);}
499       }
500     }
501   }
502   if (!rank && lg->legend) {
503     int       i,dim=lg->dim,cl;
504     PetscReal xl,yl,xr,yr,tw,th;
505     size_t    slen,len=0;
506     ierr = PetscDrawAxisGetLimits(lg->axis,&xl,&xr,&yl,&yr);CHKERRQ(ierr);
507     ierr = PetscDrawStringGetSize(draw,&tw,&th);CHKERRQ(ierr);
508     for (i=0; i<dim; i++) {
509       ierr = PetscStrlen(lg->legend[i],&slen);CHKERRQ(ierr);
510       len = PetscMax(len,slen);
511     }
512     xr = xr - 1.5*tw; xl = xr - (len + 7)*tw;
513     yr = yr - 1.0*th; yl = yr - (dim + 1)*th;
514     ierr = PetscDrawLine(draw,xl,yl,xr,yl,PETSC_DRAW_BLACK);CHKERRQ(ierr);
515     ierr = PetscDrawLine(draw,xr,yl,xr,yr,PETSC_DRAW_BLACK);CHKERRQ(ierr);
516     ierr = PetscDrawLine(draw,xr,yr,xl,yr,PETSC_DRAW_BLACK);CHKERRQ(ierr);
517     ierr = PetscDrawLine(draw,xl,yr,xl,yl,PETSC_DRAW_BLACK);CHKERRQ(ierr);
518     for  (i=0; i<dim; i++) {
519       cl   = lg->colors ? lg->colors[i] : (PETSC_DRAW_BLACK + i);
520       ierr = PetscDrawLine(draw,xl + 1*tw,yr - (i + 1)*th,xl + 5*tw,yr - (i + 1)*th,cl);CHKERRQ(ierr);
521       ierr = PetscDrawString(draw,xl + 6*tw,yr - (i + 1.5)*th,PETSC_DRAW_BLACK,lg->legend[i]);CHKERRQ(ierr);
522     }
523   }
524   ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr);
525 
526   ierr = PetscDrawFlush(draw);CHKERRQ(ierr);
527   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
528   PetscFunctionReturn(0);
529 }
530 
531 #undef __FUNCT__
532 #define __FUNCT__ "PetscDrawLGSave"
533 /*@
534   PetscDrawLGSave - Saves a drawn image
535 
536   Collective on PetscDrawLG
537 
538   Input Parameter:
539 . lg - The line graph context
540 
541   Level: intermediate
542 
543   Concepts: line graph^saving
544 
545 .seealso:  PetscDrawLGCreate(), PetscDrawLGGetDraw(), PetscDrawSetSave(), PetscDrawSave()
546 @*/
547 PetscErrorCode  PetscDrawLGSave(PetscDrawLG lg)
548 {
549   PetscErrorCode ierr;
550 
551   PetscFunctionBegin;
552   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
553   ierr = PetscDrawSave(lg->win);CHKERRQ(ierr);
554   PetscFunctionReturn(0);
555 }
556 
557 #undef __FUNCT__
558 #define __FUNCT__ "PetscDrawLGView"
559 /*@
560   PetscDrawLGView - Prints a line graph.
561 
562   Collective on PetscDrawLG
563 
564   Input Parameter:
565 . lg - the line graph context
566 
567   Level: beginner
568 
569 .keywords:  draw, line, graph
570 @*/
571 PetscErrorCode  PetscDrawLGView(PetscDrawLG lg,PetscViewer viewer)
572 {
573   PetscReal      xmin=lg->xmin, xmax=lg->xmax, ymin=lg->ymin, ymax=lg->ymax;
574   PetscInt       i, j, dim = lg->dim, nopts = lg->nopts;
575   PetscErrorCode ierr;
576 
577   PetscFunctionBegin;
578   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
579 
580   if (nopts < 1)                  PetscFunctionReturn(0);
581   if (xmin > xmax || ymin > ymax) PetscFunctionReturn(0);
582 
583   if (!viewer){
584     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg),&viewer);CHKERRQ(ierr);
585   }
586   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)lg,viewer);CHKERRQ(ierr);
587   for (i = 0; i < dim; i++) {
588     ierr = PetscViewerASCIIPrintf(viewer, "Line %D>\n", i);CHKERRQ(ierr);
589     for (j = 0; j < nopts; j++) {
590       ierr = PetscViewerASCIIPrintf(viewer, "  X: %g Y: %g\n", (double)lg->x[j*dim+i], (double)lg->y[j*dim+i]);CHKERRQ(ierr);
591     }
592   }
593   PetscFunctionReturn(0);
594 }
595 
596 #undef __FUNCT__
597 #define __FUNCT__ "PetscDrawLGSetOptionsPrefix"
598 /*@C
599    PetscDrawLGSetOptionsPrefix - Sets the prefix used for searching for all
600    PetscDrawLG options in the database.
601 
602    Logically Collective on PetscDrawLG
603 
604    Input Parameter:
605 +  lg - the line graph context
606 -  prefix - the prefix to prepend to all option names
607 
608    Level: advanced
609 
610 .keywords: PetscDrawLG, set, options, prefix, database
611 
612 .seealso: PetscDrawLGSetFromOptions()
613 @*/
614 PetscErrorCode  PetscDrawLGSetOptionsPrefix(PetscDrawLG lg,const char prefix[])
615 {
616   PetscErrorCode ierr;
617 
618   PetscFunctionBegin;
619   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
620   ierr = PetscObjectSetOptionsPrefix((PetscObject)lg,prefix);CHKERRQ(ierr);
621   PetscFunctionReturn(0);
622 }
623 
624 #undef __FUNCT__
625 #define __FUNCT__ "PetscDrawLGSetFromOptions"
626 /*@
627     PetscDrawLGSetFromOptions - Sets options related to the PetscDrawLG
628 
629     Collective on PetscDrawLG
630 
631     Options Database:
632 
633     Level: intermediate
634 
635     Concepts: line graph^creating
636 
637 .seealso:  PetscDrawLGDestroy(), PetscDrawLGCreate()
638 @*/
639 PetscErrorCode  PetscDrawLGSetFromOptions(PetscDrawLG lg)
640 {
641   PetscErrorCode      ierr;
642   PetscBool           usemarkers,set;
643   PetscDrawMarkerType markertype;
644 
645   PetscFunctionBegin;
646   PetscValidHeaderSpecific(lg,PETSC_DRAWLG_CLASSID,1);
647 
648   ierr = PetscDrawGetMarkerType(lg->win,&markertype);CHKERRQ(ierr);
649   ierr = PetscOptionsGetEnum(((PetscObject)lg)->options,((PetscObject)lg)->prefix,"-lg_marker_type",PetscDrawMarkerTypes,(PetscEnum*)&markertype,&set);CHKERRQ(ierr);
650   if (set) {
651     ierr = PetscDrawLGSetUseMarkers(lg,PETSC_TRUE);CHKERRQ(ierr);
652     ierr = PetscDrawSetMarkerType(lg->win,markertype);CHKERRQ(ierr);
653   }
654   usemarkers = lg->use_markers;
655   ierr = PetscOptionsGetBool(((PetscObject)lg)->options,((PetscObject)lg)->prefix,"-lg_use_markers",&usemarkers,&set);CHKERRQ(ierr);
656   if (set) {ierr = PetscDrawLGSetUseMarkers(lg,usemarkers);CHKERRQ(ierr);}
657   PetscFunctionReturn(0);
658 }
659