Actual source code: hists.c
2: /*
3: Contains the data structure for plotting a histogram in a window with an axis.
4: */
5: #include <petscdraw.h>
6: #include <petsc/private/petscimpl.h>
7: #include <petscviewer.h>
9: PetscClassId PETSC_DRAWHG_CLASSID = 0;
11: struct _p_PetscDrawHG {
12: PETSCHEADER(int);
13: PetscErrorCode (*destroy)(PetscDrawSP);
14: PetscErrorCode (*view)(PetscDrawSP, PetscViewer);
15: PetscDraw win;
16: PetscDrawAxis axis;
17: PetscReal xmin, xmax;
18: PetscReal ymin, ymax;
19: int numBins;
20: int maxBins;
21: PetscReal *bins;
22: int numValues;
23: int maxValues;
24: PetscReal *values;
25: int color;
26: PetscBool calcStats;
27: PetscBool integerBins;
28: };
30: #define CHUNKSIZE 100
32: /*@C
33: PetscDrawHGCreate - Creates a histogram data structure.
35: Collective
37: Input Parameters:
38: + draw - The window where the graph will be made
39: - bins - The number of bins to use
41: Output Parameters:
42: . hist - The histogram context
44: Notes:
45: The difference between a bar chart, `PetscDrawBar`, and a histogram, `PetscDrawHG`, is explained here https://stattrek.com/statistics/charts/histogram.aspx?Tutorial=AP
47: The histogram is only displayed when `PetscDrawHGDraw()` is called.
49: The MPI communicator that owns the `PetscDraw` owns this `PetscDrawHG`, but the calls to set options and add data are ignored on all processes except the
50: zeroth MPI process in the communicator. All MPI ranks in the communicator must call `PetscDrawHGDraw()` to display the updated graph.
52: Level: intermediate
54: .seealso: `PetscDrawHGDestroy()`, `PetscDrawHG`, `PetscDrawBarCreate()`, `PetscDrawBar`, `PetscDrawLGCreate()`, `PetscDrawLG`, `PetscDrawSPCreate()`, `PetscDrawSP`,
55: `PetscDrawHGSetNumberBins()`, `PetscDrawHGReset()`, `PetscDrawHGAddValue()`, `PetscDrawHGDraw()`, `PetscDrawHGSave()`, `PetscDrawHGView()`, `PetscDrawHGSetColor()`,
56: `PetscDrawHGSetLimits()`, `PetscDrawHGCalcStats()`, `PetscDrawHGIntegerBins()`, `PetscDrawHGGetAxis()`, `PetscDrawAxis`, `PetscDrawHGGetDraw()`
57: @*/
58: PetscErrorCode PetscDrawHGCreate(PetscDraw draw, int bins, PetscDrawHG *hist)
59: {
60: PetscDrawHG h;
62: PetscFunctionBegin;
67: PetscCall(PetscHeaderCreate(h, PETSC_DRAWHG_CLASSID, "DrawHG", "Histogram", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawHGDestroy, NULL));
69: PetscCall(PetscObjectReference((PetscObject)draw));
70: h->win = draw;
72: h->view = NULL;
73: h->destroy = NULL;
74: h->color = PETSC_DRAW_GREEN;
75: h->xmin = PETSC_MAX_REAL;
76: h->xmax = PETSC_MIN_REAL;
77: h->ymin = 0.;
78: h->ymax = 1.;
79: h->numBins = bins;
80: h->maxBins = bins;
82: PetscCall(PetscMalloc1(h->maxBins, &h->bins));
84: h->numValues = 0;
85: h->maxValues = CHUNKSIZE;
86: h->calcStats = PETSC_FALSE;
87: h->integerBins = PETSC_FALSE;
89: PetscCall(PetscMalloc1(h->maxValues, &h->values));
90: PetscCall(PetscDrawAxisCreate(draw, &h->axis));
92: *hist = h;
93: PetscFunctionReturn(PETSC_SUCCESS);
94: }
96: /*@
97: PetscDrawHGSetNumberBins - Change the number of bins that are to be drawn in the histogram
99: Logically Collective
101: Input Parameters:
102: + hist - The histogram context.
103: - bins - The number of bins.
105: Level: intermediate
107: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGIntegerBins()`
108: @*/
109: PetscErrorCode PetscDrawHGSetNumberBins(PetscDrawHG hist, int bins)
110: {
111: PetscFunctionBegin;
115: if (hist->maxBins < bins) {
116: PetscCall(PetscFree(hist->bins));
117: PetscCall(PetscMalloc1(bins, &hist->bins));
118: hist->maxBins = bins;
119: }
120: hist->numBins = bins;
121: PetscFunctionReturn(PETSC_SUCCESS);
122: }
124: /*@
125: PetscDrawHGReset - Clears histogram to allow for reuse with new data.
127: Logically Collective
129: Input Parameter:
130: . hist - The histogram context.
132: Level: intermediate
134: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`
135: @*/
136: PetscErrorCode PetscDrawHGReset(PetscDrawHG hist)
137: {
138: PetscFunctionBegin;
141: hist->xmin = PETSC_MAX_REAL;
142: hist->xmax = PETSC_MIN_REAL;
143: hist->ymin = 0.0;
144: hist->ymax = 1.0;
145: hist->numValues = 0;
146: PetscFunctionReturn(PETSC_SUCCESS);
147: }
149: /*@C
150: PetscDrawHGDestroy - Frees all space taken up by histogram data structure.
152: Collective
154: Input Parameter:
155: . hist - The histogram context
157: Level: intermediate
159: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`
160: @*/
161: PetscErrorCode PetscDrawHGDestroy(PetscDrawHG *hist)
162: {
163: PetscFunctionBegin;
164: if (!*hist) PetscFunctionReturn(PETSC_SUCCESS);
166: if (--((PetscObject)(*hist))->refct > 0) {
167: *hist = NULL;
168: PetscFunctionReturn(PETSC_SUCCESS);
169: }
171: PetscCall(PetscFree((*hist)->bins));
172: PetscCall(PetscFree((*hist)->values));
173: PetscCall(PetscDrawAxisDestroy(&(*hist)->axis));
174: PetscCall(PetscDrawDestroy(&(*hist)->win));
175: PetscCall(PetscHeaderDestroy(hist));
176: PetscFunctionReturn(PETSC_SUCCESS);
177: }
179: /*@
180: PetscDrawHGAddValue - Adds another value to the histogram.
182: Logically Collective
184: Input Parameters:
185: + hist - The histogram
186: - value - The value
188: Level: intermediate
190: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`, `PetscDrawHGReset()`
191: @*/
192: PetscErrorCode PetscDrawHGAddValue(PetscDrawHG hist, PetscReal value)
193: {
194: PetscFunctionBegin;
197: /* Allocate more memory if necessary */
198: if (hist->numValues >= hist->maxValues) {
199: PetscReal *tmp;
201: PetscCall(PetscMalloc1(hist->maxValues + CHUNKSIZE, &tmp));
202: PetscCall(PetscArraycpy(tmp, hist->values, hist->maxValues));
203: PetscCall(PetscFree(hist->values));
205: hist->values = tmp;
206: hist->maxValues += CHUNKSIZE;
207: }
208: /* I disagree with the original Petsc implementation here. There should be no overshoot, but rather the
209: stated convention of using half-open intervals (always the way to go) */
210: if (!hist->numValues && (hist->xmin == PETSC_MAX_REAL) && (hist->xmax == PETSC_MIN_REAL)) {
211: hist->xmin = value;
212: hist->xmax = value;
213: #if 1
214: } else {
215: /* Update limits */
216: if (value > hist->xmax) hist->xmax = value;
217: if (value < hist->xmin) hist->xmin = value;
218: #else
219: } else if (hist->numValues == 1) {
220: /* Update limits -- We need to overshoot the largest value somewhat */
221: if (value > hist->xmax) hist->xmax = value + 0.001 * (value - hist->xmin) / hist->numBins;
222: if (value < hist->xmin) {
223: hist->xmin = value;
224: hist->xmax = hist->xmax + 0.001 * (hist->xmax - hist->xmin) / hist->numBins;
225: }
226: } else {
227: /* Update limits -- We need to overshoot the largest value somewhat */
228: if (value > hist->xmax) hist->xmax = value + 0.001 * (hist->xmax - hist->xmin) / hist->numBins;
229: if (value < hist->xmin) hist->xmin = value;
230: #endif
231: }
233: hist->values[hist->numValues++] = value;
234: PetscFunctionReturn(PETSC_SUCCESS);
235: }
237: /*@
238: PetscDrawHGDraw - Redraws a histogram.
240: Collective
242: Input Parameter:
243: . hist - The histogram context
245: Level: intermediate
247: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`, `PetscDrawHGReset()`
248: @*/
249: PetscErrorCode PetscDrawHGDraw(PetscDrawHG hist)
250: {
251: PetscDraw draw;
252: PetscBool isnull;
253: PetscReal xmin, xmax, ymin, ymax, *bins, *values, binSize, binLeft, binRight, maxHeight, mean, var;
254: char title[256];
255: char xlabel[256];
256: PetscInt numBins, numBinsOld, numValues, initSize, i, p, bcolor, color;
257: PetscMPIInt rank;
259: PetscFunctionBegin;
261: PetscCall(PetscDrawIsNull(hist->win, &isnull));
262: if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
263: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)hist), &rank));
265: if ((hist->xmin >= hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(PETSC_SUCCESS);
266: if (hist->numValues < 1) PetscFunctionReturn(PETSC_SUCCESS);
268: color = hist->color;
269: if (color == PETSC_DRAW_ROTATE) bcolor = PETSC_DRAW_BLACK + 1;
270: else bcolor = color;
272: xmin = hist->xmin;
273: xmax = hist->xmax;
274: ymin = hist->ymin;
275: ymax = hist->ymax;
276: numValues = hist->numValues;
277: values = hist->values;
278: mean = 0.0;
279: var = 0.0;
281: draw = hist->win;
282: PetscCall(PetscDrawCheckResizedWindow(draw));
283: PetscCall(PetscDrawClear(draw));
285: if (xmin == xmax) {
286: /* Calculate number of points in each bin */
287: bins = hist->bins;
288: bins[0] = 0.;
289: for (p = 0; p < numValues; p++) {
290: if (values[p] == xmin) bins[0]++;
291: mean += values[p];
292: var += values[p] * values[p];
293: }
294: maxHeight = bins[0];
295: if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
296: xmax = xmin + 1;
297: PetscCall(PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax));
298: if (hist->calcStats) {
299: mean /= numValues;
300: if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1);
301: else var = 0.0;
302: PetscCall(PetscSNPrintf(title, 256, "Mean: %g Var: %g", (double)mean, (double)var));
303: PetscCall(PetscSNPrintf(xlabel, 256, "Total: %" PetscInt_FMT, numValues));
304: PetscCall(PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL));
305: }
306: PetscCall(PetscDrawAxisDraw(hist->axis));
307: PetscDrawCollectiveBegin(draw);
308: if (rank == 0) { /* Draw bins */
309: binLeft = xmin;
310: binRight = xmax;
311: PetscCall(PetscDrawRectangle(draw, binLeft, ymin, binRight, bins[0], bcolor, bcolor, bcolor, bcolor));
312: PetscCall(PetscDrawLine(draw, binLeft, ymin, binLeft, bins[0], PETSC_DRAW_BLACK));
313: PetscCall(PetscDrawLine(draw, binRight, ymin, binRight, bins[0], PETSC_DRAW_BLACK));
314: PetscCall(PetscDrawLine(draw, binLeft, bins[0], binRight, bins[0], PETSC_DRAW_BLACK));
315: }
316: PetscDrawCollectiveEnd(draw);
317: } else {
318: numBins = hist->numBins;
319: numBinsOld = hist->numBins;
320: if (hist->integerBins && (((int)xmax - xmin) + 1.0e-05 > xmax - xmin)) {
321: initSize = (int)((int)xmax - xmin) / numBins;
322: while (initSize * numBins != (int)xmax - xmin) {
323: initSize = PetscMax(initSize - 1, 1);
324: numBins = (int)((int)xmax - xmin) / initSize;
325: PetscCall(PetscDrawHGSetNumberBins(hist, numBins));
326: }
327: }
328: binSize = (xmax - xmin) / numBins;
329: bins = hist->bins;
331: PetscCall(PetscArrayzero(bins, numBins));
333: maxHeight = 0.0;
334: for (i = 0; i < numBins; i++) {
335: binLeft = xmin + binSize * i;
336: binRight = xmin + binSize * (i + 1);
337: for (p = 0; p < numValues; p++) {
338: if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
339: /* Handle last bin separately */
340: if ((i == numBins - 1) && (values[p] == binRight)) bins[i]++;
341: if (!i) {
342: mean += values[p];
343: var += values[p] * values[p];
344: }
345: }
346: maxHeight = PetscMax(maxHeight, bins[i]);
347: }
348: if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
350: PetscCall(PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax));
351: if (hist->calcStats) {
352: mean /= numValues;
353: if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1);
354: else var = 0.0;
355: PetscCall(PetscSNPrintf(title, 256, "Mean: %g Var: %g", (double)mean, (double)var));
356: PetscCall(PetscSNPrintf(xlabel, 256, "Total: %" PetscInt_FMT, numValues));
357: PetscCall(PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL));
358: }
359: PetscCall(PetscDrawAxisDraw(hist->axis));
360: PetscDrawCollectiveBegin(draw);
361: if (rank == 0) { /* Draw bins */
362: for (i = 0; i < numBins; i++) {
363: binLeft = xmin + binSize * i;
364: binRight = xmin + binSize * (i + 1);
365: PetscCall(PetscDrawRectangle(draw, binLeft, ymin, binRight, bins[i], bcolor, bcolor, bcolor, bcolor));
366: PetscCall(PetscDrawLine(draw, binLeft, ymin, binLeft, bins[i], PETSC_DRAW_BLACK));
367: PetscCall(PetscDrawLine(draw, binRight, ymin, binRight, bins[i], PETSC_DRAW_BLACK));
368: PetscCall(PetscDrawLine(draw, binLeft, bins[i], binRight, bins[i], PETSC_DRAW_BLACK));
369: if (color == PETSC_DRAW_ROTATE && bins[i]) bcolor++;
370: if (bcolor > PETSC_DRAW_BASIC_COLORS - 1) bcolor = PETSC_DRAW_BLACK + 1;
371: }
372: }
373: PetscDrawCollectiveEnd(draw);
374: PetscCall(PetscDrawHGSetNumberBins(hist, numBinsOld));
375: }
377: PetscCall(PetscDrawFlush(draw));
378: PetscCall(PetscDrawPause(draw));
379: PetscFunctionReturn(PETSC_SUCCESS);
380: }
382: /*@
383: PetscDrawHGSave - Saves a drawn image
385: Collective
387: Input Parameter:
388: . hist - The histogram context
390: Level: intermediate
392: .seealso: `PetscDrawSave()`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`
393: @*/
394: PetscErrorCode PetscDrawHGSave(PetscDrawHG hg)
395: {
396: PetscFunctionBegin;
398: PetscCall(PetscDrawSave(hg->win));
399: PetscFunctionReturn(PETSC_SUCCESS);
400: }
402: /*@
403: PetscDrawHGView - Prints the histogram information to a viewer
405: Not collective
407: Input Parameter:
408: . hist - The histogram context
410: Level: beginner
412: .seealso: `PetscDrawHG`, `PetscViewer`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`
413: @*/
414: PetscErrorCode PetscDrawHGView(PetscDrawHG hist, PetscViewer viewer)
415: {
416: PetscReal xmax, xmin, *bins, *values, binSize, binLeft, binRight, mean, var;
417: PetscInt numBins, numBinsOld, numValues, initSize, i, p;
419: PetscFunctionBegin;
422: if ((hist->xmin > hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(PETSC_SUCCESS);
423: if (hist->numValues < 1) PetscFunctionReturn(PETSC_SUCCESS);
425: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)hist), &viewer));
426: PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)hist, viewer));
427: xmax = hist->xmax;
428: xmin = hist->xmin;
429: numValues = hist->numValues;
430: values = hist->values;
431: mean = 0.0;
432: var = 0.0;
433: if (xmax == xmin) {
434: /* Calculate number of points in the bin */
435: bins = hist->bins;
436: bins[0] = 0.;
437: for (p = 0; p < numValues; p++) {
438: if (values[p] == xmin) bins[0]++;
439: mean += values[p];
440: var += values[p] * values[p];
441: }
442: /* Draw bins */
443: PetscCall(PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", 0, (double)xmin, (double)xmax, (double)bins[0]));
444: } else {
445: numBins = hist->numBins;
446: numBinsOld = hist->numBins;
447: if (hist->integerBins && (((int)xmax - xmin) + 1.0e-05 > xmax - xmin)) {
448: initSize = (int)((int)xmax - xmin) / numBins;
449: while (initSize * numBins != (int)xmax - xmin) {
450: initSize = PetscMax(initSize - 1, 1);
451: numBins = (int)((int)xmax - xmin) / initSize;
452: PetscCall(PetscDrawHGSetNumberBins(hist, numBins));
453: }
454: }
455: binSize = (xmax - xmin) / numBins;
456: bins = hist->bins;
458: /* Calculate number of points in each bin */
459: PetscCall(PetscArrayzero(bins, numBins));
460: for (i = 0; i < numBins; i++) {
461: binLeft = xmin + binSize * i;
462: binRight = xmin + binSize * (i + 1);
463: for (p = 0; p < numValues; p++) {
464: if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
465: /* Handle last bin separately */
466: if ((i == numBins - 1) && (values[p] == binRight)) bins[i]++;
467: if (!i) {
468: mean += values[p];
469: var += values[p] * values[p];
470: }
471: }
472: }
473: /* Draw bins */
474: for (i = 0; i < numBins; i++) {
475: binLeft = xmin + binSize * i;
476: binRight = xmin + binSize * (i + 1);
477: PetscCall(PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", (int)i, (double)binLeft, (double)binRight, (double)bins[i]));
478: }
479: PetscCall(PetscDrawHGSetNumberBins(hist, numBinsOld));
480: }
482: if (hist->calcStats) {
483: mean /= numValues;
484: if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1);
485: else var = 0.0;
486: PetscCall(PetscViewerASCIIPrintf(viewer, "Mean: %g Var: %g\n", (double)mean, (double)var));
487: PetscCall(PetscViewerASCIIPrintf(viewer, "Total: %" PetscInt_FMT "\n", numValues));
488: }
489: PetscFunctionReturn(PETSC_SUCCESS);
490: }
492: /*@
493: PetscDrawHGSetColor - Sets the color the bars will be drawn with.
495: Logically Collective
497: Input Parameters:
498: + hist - The histogram context
499: - color - one of the colors defined in petscdraw.h or `PETSC_DRAW_ROTATE` to make each bar a
500: different color
502: Level: intermediate
504: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`, `PetscDrawHGGetAxis()`
505: @*/
506: PetscErrorCode PetscDrawHGSetColor(PetscDrawHG hist, int color)
507: {
508: PetscFunctionBegin;
511: hist->color = color;
512: PetscFunctionReturn(PETSC_SUCCESS);
513: }
515: /*@
516: PetscDrawHGSetLimits - Sets the axis limits for a histogram. If more
517: points are added after this call, the limits will be adjusted to
518: include those additional points.
520: Logically Collective
522: Input Parameters:
523: + hist - The histogram context
524: - x_min,x_max,y_min,y_max - The limits
526: Level: intermediate
528: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`, `PetscDrawHGGetAxis()`
529: @*/
530: PetscErrorCode PetscDrawHGSetLimits(PetscDrawHG hist, PetscReal x_min, PetscReal x_max, int y_min, int y_max)
531: {
532: PetscFunctionBegin;
535: hist->xmin = x_min;
536: hist->xmax = x_max;
537: hist->ymin = y_min;
538: hist->ymax = y_max;
539: PetscFunctionReturn(PETSC_SUCCESS);
540: }
542: /*@
543: PetscDrawHGCalcStats - Turns on calculation of descriptive statistics associated with the histogram
545: Not collective
547: Input Parameters:
548: + hist - The histogram context
549: - calc - Flag for calculation
551: Level: intermediate
553: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`
554: @*/
555: PetscErrorCode PetscDrawHGCalcStats(PetscDrawHG hist, PetscBool calc)
556: {
557: PetscFunctionBegin;
560: hist->calcStats = calc;
561: PetscFunctionReturn(PETSC_SUCCESS);
562: }
564: /*@
565: PetscDrawHGIntegerBins - Turns on integer width bins
567: Not collective
569: Input Parameters:
570: + hist - The histogram context
571: - ints - Flag for integer width bins
573: Level: intermediate
575: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`
576: @*/
577: PetscErrorCode PetscDrawHGIntegerBins(PetscDrawHG hist, PetscBool ints)
578: {
579: PetscFunctionBegin;
582: hist->integerBins = ints;
583: PetscFunctionReturn(PETSC_SUCCESS);
584: }
586: /*@C
587: PetscDrawHGGetAxis - Gets the axis context associated with a histogram.
588: This is useful if one wants to change some axis property, such as
589: labels, color, etc. The axis context should not be destroyed by the
590: application code.
592: Not Collective, axis is parallel if hist is parallel
594: Input Parameter:
595: . hist - The histogram context
597: Output Parameter:
598: . axis - The axis context
600: Level: intermediate
602: .seealso: `PetscDrawHG`, `PetscDrawAxis`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`, `PetscDrawAxis`, `PetscDrawHGSetLimits()`
603: @*/
604: PetscErrorCode PetscDrawHGGetAxis(PetscDrawHG hist, PetscDrawAxis *axis)
605: {
606: PetscFunctionBegin;
609: *axis = hist->axis;
610: PetscFunctionReturn(PETSC_SUCCESS);
611: }
613: /*@C
614: PetscDrawHGGetDraw - Gets the draw context associated with a histogram.
616: Not Collective, draw is parallel if hist is parallel
618: Input Parameter:
619: . hist - The histogram context
621: Output Parameter:
622: . draw - The draw context
624: Level: intermediate
626: .seealso: `PetscDraw`, `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`, `PetscDrawAxis`, `PetscDrawHGSetLimits()`
627: @*/
628: PetscErrorCode PetscDrawHGGetDraw(PetscDrawHG hist, PetscDraw *draw)
629: {
630: PetscFunctionBegin;
633: *draw = hist->win;
634: PetscFunctionReturn(PETSC_SUCCESS);
635: }