Date: 2025-03-29T05:58:42+00:00

Actual source code: lgc.c

      1: #include <petscviewer.h>
      2: #include <petsc/private/drawimpl.h>
      3: PetscClassId PETSC_DRAWLG_CLASSID = 0;

      5: /*@
      6:   PetscDrawLGGetAxis - Gets the axis context associated with a line graph.
      7:   This is useful if one wants to change some axis property, such as
      8:   labels, color, etc. The axis context should not be destroyed by the
      9:   application code.

     11:   Not Collective, if lg is parallel then axis is parallel

     13:   Input Parameter:
     14: . lg - the line graph context

     16:   Output Parameter:
     17: . axis - the axis context

     19:   Level: advanced

     21: .seealso: `PetscDrawLGCreate()`, `PetscDrawAxis`, `PetscDrawLG`
     22: @*/
     23: PetscErrorCode PetscDrawLGGetAxis(PetscDrawLG lg, PetscDrawAxis *axis)
     24: {
     25:   PetscFunctionBegin;
     27:   PetscAssertPointer(axis, 2);
     28:   *axis = lg->axis;
     29:   PetscFunctionReturn(PETSC_SUCCESS);
     30: }

     32: /*@
     33:   PetscDrawLGGetDraw - Gets the draw context associated with a line graph.

     35:   Not Collective, if lg is parallel then draw is parallel

     37:   Input Parameter:
     38: . lg - the line graph context

     40:   Output Parameter:
     41: . draw - the draw context

     43:   Level: intermediate

     45: .seealso: `PetscDrawLGCreate()`, `PetscDraw`, `PetscDrawLG`
     46: @*/
     47: PetscErrorCode PetscDrawLGGetDraw(PetscDrawLG lg, PetscDraw *draw)
     48: {
     49:   PetscFunctionBegin;
     51:   PetscAssertPointer(draw, 2);
     52:   *draw = lg->win;
     53:   PetscFunctionReturn(PETSC_SUCCESS);
     54: }

     56: /*@
     57:   PetscDrawLGSPDraw - Redraws a line graph and a scatter plot on the same `PetscDraw` they must share

     59:   Collective

     61:   Input Parameters:
     62: + lg   - the line graph context
     63: - spin - the scatter plot

     65:   Level: intermediate

     67:   Developer Notes:
     68:   This code cheats and uses the fact that the `PetscDrawLG` and `PetscDrawSP` structs are the same

     70: .seealso: `PetscDrawLGDraw()`, `PetscDrawSPDraw()`
     71: @*/
     72: PetscErrorCode PetscDrawLGSPDraw(PetscDrawLG lg, PetscDrawSP spin)
     73: {
     74:   PetscDrawLG sp = (PetscDrawLG)spin;
     75:   PetscReal   xmin, xmax, ymin, ymax;
     76:   PetscBool   isnull;
     77:   PetscMPIInt rank;
     78:   PetscDraw   draw;

     80:   PetscFunctionBegin;
     83:   PetscCall(PetscDrawIsNull(lg->win, &isnull));
     84:   if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
     85:   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)lg), &rank));

     87:   draw = lg->win;
     88:   PetscCall(PetscDrawCheckResizedWindow(draw));
     89:   PetscCall(PetscDrawClear(draw));

     91:   xmin = PetscMin(lg->xmin, sp->xmin);
     92:   ymin = PetscMin(lg->ymin, sp->ymin);
     93:   xmax = PetscMax(lg->xmax, sp->xmax);
     94:   ymax = PetscMax(lg->ymax, sp->ymax);
     95:   PetscCall(PetscDrawAxisSetLimits(lg->axis, xmin, xmax, ymin, ymax));
     96:   PetscCall(PetscDrawAxisDraw(lg->axis));

     98:   PetscDrawCollectiveBegin(draw);
     99:   if (rank == 0) {
    100:     int i, j, dim, nopts;
    101:     dim   = lg->dim;
    102:     nopts = lg->nopts;
    103:     for (i = 0; i < dim; i++) {
    104:       for (j = 1; j < nopts; j++) {
    105:         PetscCall(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));
    106:         if (lg->use_markers) PetscCall(PetscDrawMarker(draw, lg->x[j * dim + i], lg->y[j * dim + i], PETSC_DRAW_RED));
    107:       }
    108:     }
    109:     dim   = sp->dim;
    110:     nopts = sp->nopts;
    111:     for (i = 0; i < dim; i++) {
    112:       for (j = 0; j < nopts; j++) PetscCall(PetscDrawMarker(draw, sp->x[j * dim + i], sp->y[j * dim + i], PETSC_DRAW_RED));
    113:     }
    114:   }
    115:   PetscDrawCollectiveEnd(draw);

    117:   PetscCall(PetscDrawFlush(draw));
    118:   PetscCall(PetscDrawPause(draw));
    119:   PetscFunctionReturn(PETSC_SUCCESS);
    120: }

    122: /*@
    123:   PetscDrawLGCreate - Creates a line graph data structure.

    125:   Collective

    127:   Input Parameters:
    128: + draw - the window where the graph will be made.
    129: - dim  - the number of curves which will be drawn

    131:   Output Parameter:
    132: . outlg - the line graph context

    134:   Level: intermediate

    136:   Notes:
    137:   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
    138:   zeroth MPI process in the communicator.

    140:   All MPI ranks in the communicator must call `PetscDrawLGDraw()` to display the updated graph.

    142: .seealso: `PetscDrawLGDestroy()`, `PetscDrawLGAddPoint()`, `PetscDrawLGAddCommonPoint()`, `PetscDrawLGAddPoints()`, `PetscDrawLGDraw()`, `PetscDrawLGSave()`,
    143:           `PetscDrawLGView()`, `PetscDrawLGReset()`, `PetscDrawLGSetDimension()`, `PetscDrawLGGetDimension()`, `PetscDrawLGSetLegend()`, `PetscDrawLGGetAxis()`,
    144:           `PetscDrawLGGetDraw()`, `PetscDrawLGSetUseMarkers()`, `PetscDrawLGSetLimits()`, `PetscDrawLGSetColors()`, `PetscDrawLGSetOptionsPrefix()`, `PetscDrawLGSetFromOptions()`
    145: @*/
    146: PetscErrorCode PetscDrawLGCreate(PetscDraw draw, PetscInt dim, PetscDrawLG *outlg)
    147: {
    148:   PetscDrawLG lg;

    150:   PetscFunctionBegin;
    153:   PetscAssertPointer(outlg, 3);

    155:   PetscCall(PetscHeaderCreate(lg, PETSC_DRAWLG_CLASSID, "DrawLG", "Line Graph", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawLGDestroy, NULL));
    156:   PetscCall(PetscDrawLGSetOptionsPrefix(lg, ((PetscObject)draw)->prefix));

    158:   PetscCall(PetscObjectReference((PetscObject)draw));
    159:   lg->win = draw;

    161:   lg->view    = NULL;
    162:   lg->destroy = NULL;
    163:   lg->nopts   = 0;
    164:   lg->xmin    = 1.e20;
    165:   lg->ymin    = 1.e20;
    166:   lg->xmax    = -1.e20;
    167:   lg->ymax    = -1.e20;
    168:   PetscCall(PetscCIntCast(dim, &lg->dim));
    169:   PetscCall(PetscMalloc2(dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->x, dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->y));

    171:   lg->len         = lg->dim * PETSC_DRAW_LG_CHUNK_SIZE;
    172:   lg->loc         = 0;
    173:   lg->use_markers = PETSC_FALSE;

    175:   PetscCall(PetscDrawAxisCreate(draw, &lg->axis));

    177:   *outlg = lg;
    178:   PetscFunctionReturn(PETSC_SUCCESS);
    179: }

    181: /*@
    182:   PetscDrawLGSetColors - Sets the color of each line graph drawn

    184:   Logically Collective

    186:   Input Parameters:
    187: + lg     - the line graph context.
    188: - colors - the colors, an array of length the value set with `PetscDrawLGSetDimension()`

    190:   Level: intermediate

    192: .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`, `PetscDrawLGSetDimension()`, `PetscDrawLGGetDimension()`
    193: @*/
    194: PetscErrorCode PetscDrawLGSetColors(PetscDrawLG lg, const int colors[])
    195: {
    196:   PetscFunctionBegin;
    198:   if (lg->dim) PetscAssertPointer(colors, 2);

    200:   PetscCall(PetscFree(lg->colors));
    201:   PetscCall(PetscMalloc1(lg->dim, &lg->colors));
    202:   PetscCall(PetscArraycpy(lg->colors, colors, lg->dim));
    203:   PetscFunctionReturn(PETSC_SUCCESS);
    204: }

    206: /*@C
    207:   PetscDrawLGSetLegend - sets the names of each curve plotted

    209:   Logically Collective

    211:   Input Parameters:
    212: + lg    - the line graph context.
    213: - names - the names for each curve

    215:   Level: intermediate

    217:   Note:
    218:   Call `PetscDrawLGGetAxis()` and then change properties of the `PetscDrawAxis` for detailed control of the plot

    220: .seealso: `PetscDrawLGGetAxis()`, `PetscDrawAxis`, `PetscDrawAxisSetColors()`, `PetscDrawAxisSetLabels()`, `PetscDrawAxisSetHoldLimits()`
    221: @*/
    222: PetscErrorCode PetscDrawLGSetLegend(PetscDrawLG lg, const char *const names[])
    223: {
    224:   PetscInt i;

    226:   PetscFunctionBegin;
    228:   if (names) PetscAssertPointer(names, 2);

    230:   if (lg->legend) {
    231:     for (i = 0; i < lg->dim; i++) PetscCall(PetscFree(lg->legend[i]));
    232:     PetscCall(PetscFree(lg->legend));
    233:   }
    234:   if (names) {
    235:     PetscCall(PetscMalloc1(lg->dim, &lg->legend));
    236:     for (i = 0; i < lg->dim; i++) PetscCall(PetscStrallocpy(names[i], &lg->legend[i]));
    237:   }
    238:   PetscFunctionReturn(PETSC_SUCCESS);
    239: }

    241: /*@
    242:   PetscDrawLGGetDimension - Get the number of curves that are to be drawn.

    244:   Not Collective

    246:   Input Parameter:
    247: . lg - the line graph context.

    249:   Output Parameter:
    250: . dim - the number of curves.

    252:   Level: intermediate

    254: .seealso: `PetscDrawLGC`, `PetscDrawLGCreate()`, `PetscDrawLGSetDimension()`
    255: @*/
    256: PetscErrorCode PetscDrawLGGetDimension(PetscDrawLG lg, PetscInt *dim)
    257: {
    258:   PetscFunctionBegin;
    260:   PetscAssertPointer(dim, 2);
    261:   *dim = lg->dim;
    262:   PetscFunctionReturn(PETSC_SUCCESS);
    263: }

    265: /*@
    266:   PetscDrawLGSetDimension - Change the number of curves that are to be drawn.

    268:   Logically Collective

    270:   Input Parameters:
    271: + lg  - the line graph context.
    272: - dim - the number of curves.

    274:   Level: intermediate

    276: .seealso: `PetscDrawLGCreate()`, `PetscDrawLGGetDimension()`
    277: @*/
    278: PetscErrorCode PetscDrawLGSetDimension(PetscDrawLG lg, PetscInt dim)
    279: {
    280:   PetscInt i;

    282:   PetscFunctionBegin;
    285:   if (lg->dim == dim) PetscFunctionReturn(PETSC_SUCCESS);

    287:   PetscCall(PetscFree2(lg->x, lg->y));
    288:   if (lg->legend) {
    289:     for (i = 0; i < lg->dim; i++) PetscCall(PetscFree(lg->legend[i]));
    290:     PetscCall(PetscFree(lg->legend));
    291:   }
    292:   PetscCall(PetscFree(lg->colors));
    293:   PetscCall(PetscCIntCast(dim, &lg->dim));
    294:   PetscCall(PetscMalloc2(dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->x, dim * PETSC_DRAW_LG_CHUNK_SIZE, &lg->y));
    295:   lg->len = lg->dim * PETSC_DRAW_LG_CHUNK_SIZE;
    296:   PetscFunctionReturn(PETSC_SUCCESS);
    297: }

    299: /*@
    300:   PetscDrawLGSetLimits - Sets the axis limits for a line graph. If more
    301:   points are added after this call, the limits will be adjusted to
    302:   include those additional points.

    304:   Logically Collective

    306:   Input Parameters:
    307: + lg    - the line graph context
    308: . x_min - the horizontal lower limit
    309: . x_max - the horizontal upper limit
    310: . y_min - the vertical lower limit
    311: - y_max - the vertical upper limit

    313:   Level: intermediate

    315: .seealso: `PetscDrawLGCreate()`, `PetscDrawLG`, `PetscDrawAxis`
    316: @*/
    317: PetscErrorCode PetscDrawLGSetLimits(PetscDrawLG lg, PetscReal x_min, PetscReal x_max, PetscReal y_min, PetscReal y_max)
    318: {
    319:   PetscFunctionBegin;

    322:   (lg)->xmin = x_min;
    323:   (lg)->xmax = x_max;
    324:   (lg)->ymin = y_min;
    325:   (lg)->ymax = y_max;
    326:   PetscFunctionReturn(PETSC_SUCCESS);
    327: }

    329: /*@
    330:   PetscDrawLGReset - Clears line graph to allow for reuse with new data.

    332:   Logically Collective

    334:   Input Parameter:
    335: . lg - the line graph context.

    337:   Level: intermediate

    339: .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
    340: @*/
    341: PetscErrorCode PetscDrawLGReset(PetscDrawLG lg)
    342: {
    343:   PetscFunctionBegin;
    345:   lg->xmin  = 1.e20;
    346:   lg->ymin  = 1.e20;
    347:   lg->xmax  = -1.e20;
    348:   lg->ymax  = -1.e20;
    349:   lg->loc   = 0;
    350:   lg->nopts = 0;
    351:   PetscFunctionReturn(PETSC_SUCCESS);
    352: }

    354: /*@
    355:   PetscDrawLGDestroy - Frees all space taken up by line graph data structure.

    357:   Collective

    359:   Input Parameter:
    360: . lg - the line graph context

    362:   Level: intermediate

    364: .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
    365: @*/
    366: PetscErrorCode PetscDrawLGDestroy(PetscDrawLG *lg)
    367: {
    368:   PetscInt i;

    370:   PetscFunctionBegin;
    371:   if (!*lg) PetscFunctionReturn(PETSC_SUCCESS);
    373:   if (--((PetscObject)*lg)->refct > 0) {
    374:     *lg = NULL;
    375:     PetscFunctionReturn(PETSC_SUCCESS);
    376:   }

    378:   if ((*lg)->legend) {
    379:     for (i = 0; i < (*lg)->dim; i++) PetscCall(PetscFree((*lg)->legend[i]));
    380:     PetscCall(PetscFree((*lg)->legend));
    381:   }
    382:   PetscCall(PetscFree((*lg)->colors));
    383:   PetscCall(PetscFree2((*lg)->x, (*lg)->y));
    384:   PetscCall(PetscDrawAxisDestroy(&(*lg)->axis));
    385:   PetscCall(PetscDrawDestroy(&(*lg)->win));
    386:   PetscCall(PetscHeaderDestroy(lg));
    387:   PetscFunctionReturn(PETSC_SUCCESS);
    388: }
    389: /*@
    390:   PetscDrawLGSetUseMarkers - Causes the line graph object to draw a marker for each data-point.

    392:   Logically Collective

    394:   Input Parameters:
    395: + lg  - the linegraph context
    396: - flg - should mark each data point

    398:   Options Database Key:
    399: . -lg_use_markers  <true,false> - true means it draws a marker for each point

    401:   Level: intermediate

    403: .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
    404: @*/
    405: PetscErrorCode PetscDrawLGSetUseMarkers(PetscDrawLG lg, PetscBool flg)
    406: {
    407:   PetscFunctionBegin;
    410:   lg->use_markers = flg;
    411:   PetscFunctionReturn(PETSC_SUCCESS);
    412: }

    414: /*@
    415:   PetscDrawLGDraw - Redraws a line graph.

    417:   Collective

    419:   Input Parameter:
    420: . lg - the line graph context

    422:   Level: intermediate

    424: .seealso: `PetscDrawLG`, `PetscDrawSPDraw()`, `PetscDrawLGSPDraw()`, `PetscDrawLGReset()`
    425: @*/
    426: PetscErrorCode PetscDrawLGDraw(PetscDrawLG lg)
    427: {
    428:   PetscReal   xmin, xmax, ymin, ymax;
    429:   PetscMPIInt rank;
    430:   PetscDraw   draw;
    431:   PetscBool   isnull;

    433:   PetscFunctionBegin;
    435:   PetscCall(PetscDrawIsNull(lg->win, &isnull));
    436:   if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
    437:   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)lg), &rank));

    439:   draw = lg->win;
    440:   PetscCall(PetscDrawCheckResizedWindow(draw));
    441:   PetscCall(PetscDrawClear(draw));

    443:   xmin = lg->xmin;
    444:   xmax = lg->xmax;
    445:   ymin = lg->ymin;
    446:   ymax = lg->ymax;
    447:   // Try not to freak out the axis
    448:   if (ymax - ymin < PETSC_SMALL) {
    449:     ymin -= 0.1 * ymax;
    450:     ymax += 0.1 * ymax;
    451:   }
    452:   PetscCall(PetscDrawAxisSetLimits(lg->axis, xmin, xmax, ymin, ymax));
    453:   PetscCall(PetscDrawAxisDraw(lg->axis));

    455:   PetscDrawCollectiveBegin(draw);
    456:   if (rank == 0) {
    457:     int i, j, dim = lg->dim, nopts = lg->nopts, cl;
    458:     for (i = 0; i < dim; i++) {
    459:       for (j = 1; j < nopts; j++) {
    460:         cl = lg->colors ? lg->colors[i] : ((PETSC_DRAW_BLACK + i) % PETSC_DRAW_MAXCOLOR);
    461:         PetscCall(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));
    462:         if (lg->use_markers) PetscCall(PetscDrawMarker(draw, lg->x[j * dim + i], lg->y[j * dim + i], cl));
    463:       }
    464:     }
    465:   }
    466:   if (rank == 0 && lg->legend) {
    467:     PetscBool right = PETSC_FALSE;
    468:     int       i, dim = lg->dim, cl;
    469:     PetscReal xl, yl, xr, yr, tw, th;
    470:     size_t    slen, len = 0;

    472:     PetscCall(PetscDrawAxisGetLimits(lg->axis, &xl, &xr, &yl, &yr));
    473:     PetscCall(PetscDrawStringGetSize(draw, &tw, &th));
    474:     for (i = 0; i < dim; i++) {
    475:       PetscCall(PetscStrlen(lg->legend[i], &slen));
    476:       len = PetscMax(len, slen);
    477:     }
    478:     if (right) {
    479:       xr = xr - 1.5 * tw;
    480:       xl = xr - ((PetscReal)len + 7) * tw;
    481:     } else {
    482:       xl = xl + 1.5 * tw;
    483:       xr = xl + ((PetscReal)len + 7) * tw;
    484:     }
    485:     yr = yr - 1.0 * th;
    486:     yl = yr - (dim + 1) * th;
    487:     PetscCall(PetscDrawLine(draw, xl, yl, xr, yl, PETSC_DRAW_BLACK));
    488:     PetscCall(PetscDrawLine(draw, xr, yl, xr, yr, PETSC_DRAW_BLACK));
    489:     PetscCall(PetscDrawLine(draw, xr, yr, xl, yr, PETSC_DRAW_BLACK));
    490:     PetscCall(PetscDrawLine(draw, xl, yr, xl, yl, PETSC_DRAW_BLACK));
    491:     for (i = 0; i < dim; i++) {
    492:       cl = lg->colors ? lg->colors[i] : (PETSC_DRAW_BLACK + i);
    493:       PetscCall(PetscDrawLine(draw, xl + 1 * tw, yr - (i + 1) * th, xl + 5 * tw, yr - (i + 1) * th, cl));
    494:       PetscCall(PetscDrawString(draw, xl + 6 * tw, yr - (i + 1.5) * th, PETSC_DRAW_BLACK, lg->legend[i]));
    495:     }
    496:   }
    497:   PetscDrawCollectiveEnd(draw);

    499:   PetscCall(PetscDrawFlush(draw));
    500:   PetscCall(PetscDrawPause(draw));
    501:   PetscFunctionReturn(PETSC_SUCCESS);
    502: }

    504: /*@
    505:   PetscDrawLGSave - Saves a drawn image

    507:   Collective

    509:   Input Parameter:
    510: . lg - The line graph context

    512:   Level: intermediate

    514: .seealso: `PetscDrawLG`, `PetscDrawSave()`, `PetscDrawLGCreate()`, `PetscDrawLGGetDraw()`, `PetscDrawSetSave()`
    515: @*/
    516: PetscErrorCode PetscDrawLGSave(PetscDrawLG lg)
    517: {
    518:   PetscFunctionBegin;
    520:   PetscCall(PetscDrawSave(lg->win));
    521:   PetscFunctionReturn(PETSC_SUCCESS);
    522: }

    524: /*@
    525:   PetscDrawLGView - Prints a line graph.

    527:   Collective

    529:   Input Parameters:
    530: + lg     - the line graph context
    531: - viewer - the viewer to view it with

    533:   Level: beginner

    535: .seealso: `PetscDrawLG`, `PetscDrawLGCreate()`
    536: @*/
    537: PetscErrorCode PetscDrawLGView(PetscDrawLG lg, PetscViewer viewer)
    538: {
    539:   PetscReal xmin = lg->xmin, xmax = lg->xmax, ymin = lg->ymin, ymax = lg->ymax;
    540:   PetscInt  i, j, dim = lg->dim, nopts = lg->nopts;

    542:   PetscFunctionBegin;

    545:   if (nopts < 1) PetscFunctionReturn(PETSC_SUCCESS);
    546:   if (xmin > xmax || ymin > ymax) PetscFunctionReturn(PETSC_SUCCESS);

    548:   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)lg), &viewer));
    549:   PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)lg, viewer));
    550:   for (i = 0; i < dim; i++) {
    551:     PetscCall(PetscViewerASCIIPrintf(viewer, "Line %" PetscInt_FMT ">\n", i));
    552:     for (j = 0; j < nopts; j++) PetscCall(PetscViewerASCIIPrintf(viewer, "  X: %g Y: %g\n", (double)lg->x[j * dim + i], (double)lg->y[j * dim + i]));
    553:   }
    554:   PetscFunctionReturn(PETSC_SUCCESS);
    555: }

    557: /*@
    558:   PetscDrawLGSetOptionsPrefix - Sets the prefix used for searching for all
    559:   `PetscDrawLG` options in the database.

    561:   Logically Collective

    563:   Input Parameters:
    564: + lg     - the line graph context
    565: - prefix - the prefix to prepend to all option names

    567:   Level: advanced

    569: .seealso: `PetscDrawLG`, `PetscDrawLGSetFromOptions()`, `PetscDrawLGCreate()`
    570: @*/
    571: PetscErrorCode PetscDrawLGSetOptionsPrefix(PetscDrawLG lg, const char prefix[])
    572: {
    573:   PetscFunctionBegin;
    575:   PetscCall(PetscObjectSetOptionsPrefix((PetscObject)lg, prefix));
    576:   PetscFunctionReturn(PETSC_SUCCESS);
    577: }

    579: /*@
    580:   PetscDrawLGSetFromOptions - Sets options related to the line graph object

    582:   Collective

    584:   Input Parameters:
    585: . lg - the line graph context

    587:   Options Database Key:
    588: . -lg_use_markers  <true,false> - true means it draws a marker for each point

    590:   Level: intermediate

    592: .seealso: `PetscDrawLG`, `PetscDrawLGDestroy()`, `PetscDrawLGCreate()`
    593: @*/
    594: PetscErrorCode PetscDrawLGSetFromOptions(PetscDrawLG lg)
    595: {
    596:   PetscBool           usemarkers, set;
    597:   PetscDrawMarkerType markertype;

    599:   PetscFunctionBegin;

    602:   PetscCall(PetscDrawGetMarkerType(lg->win, &markertype));
    603:   PetscCall(PetscOptionsGetEnum(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_marker_type", PetscDrawMarkerTypes, (PetscEnum *)&markertype, &set));
    604:   if (set) {
    605:     PetscCall(PetscDrawLGSetUseMarkers(lg, PETSC_TRUE));
    606:     PetscCall(PetscDrawSetMarkerType(lg->win, markertype));
    607:   }
    608:   usemarkers = lg->use_markers;
    609:   PetscCall(PetscOptionsGetBool(((PetscObject)lg)->options, ((PetscObject)lg)->prefix, "-lg_use_markers", &usemarkers, &set));
    610:   if (set) PetscCall(PetscDrawLGSetUseMarkers(lg, usemarkers));
    611:   PetscFunctionReturn(PETSC_SUCCESS);
    612: }