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 Parameter:
42: . hist - The histogram context
44: Level: intermediate
46: Notes:
47: The difference between a bar chart, `PetscDrawBar`, and a histogram, `PetscDrawHG`, is explained here https://stattrek.com/statistics/charts/histogram.aspx?Tutorial=AP
49: The histogram is only displayed when `PetscDrawHGDraw()` is called.
51: 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
52: zeroth MPI process in the communicator. All MPI ranks in the communicator must call `PetscDrawHGDraw()` to display the updated graph.
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 different color
501: Level: intermediate
503: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`, `PetscDrawHGGetAxis()`
504: @*/
505: PetscErrorCode PetscDrawHGSetColor(PetscDrawHG hist, int color)
506: {
507: PetscFunctionBegin;
510: hist->color = color;
511: PetscFunctionReturn(PETSC_SUCCESS);
512: }
514: /*@
515: PetscDrawHGSetLimits - Sets the axis limits for a histogram. If more
516: points are added after this call, the limits will be adjusted to
517: include those additional points.
519: Logically Collective
521: Input Parameters:
522: + hist - The histogram context
523: . x_min - the horizontal lower limit
524: . x_max - the horizontal upper limit
525: . y_min - the vertical lower limit
526: - y_max - the vertical upper limit
528: Level: intermediate
530: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`, `PetscDrawHGGetAxis()`
531: @*/
532: PetscErrorCode PetscDrawHGSetLimits(PetscDrawHG hist, PetscReal x_min, PetscReal x_max, int y_min, int y_max)
533: {
534: PetscFunctionBegin;
537: hist->xmin = x_min;
538: hist->xmax = x_max;
539: hist->ymin = y_min;
540: hist->ymax = y_max;
541: PetscFunctionReturn(PETSC_SUCCESS);
542: }
544: /*@
545: PetscDrawHGCalcStats - Turns on calculation of descriptive statistics associated with the histogram
547: Not Collective
549: Input Parameters:
550: + hist - The histogram context
551: - calc - Flag for calculation
553: Level: intermediate
555: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`
556: @*/
557: PetscErrorCode PetscDrawHGCalcStats(PetscDrawHG hist, PetscBool calc)
558: {
559: PetscFunctionBegin;
562: hist->calcStats = calc;
563: PetscFunctionReturn(PETSC_SUCCESS);
564: }
566: /*@
567: PetscDrawHGIntegerBins - Turns on integer width bins
569: Not Collective
571: Input Parameters:
572: + hist - The histogram context
573: - ints - Flag for integer width bins
575: Level: intermediate
577: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`
578: @*/
579: PetscErrorCode PetscDrawHGIntegerBins(PetscDrawHG hist, PetscBool ints)
580: {
581: PetscFunctionBegin;
584: hist->integerBins = ints;
585: PetscFunctionReturn(PETSC_SUCCESS);
586: }
588: /*@C
589: PetscDrawHGGetAxis - Gets the axis context associated with a histogram.
590: This is useful if one wants to change some axis property, such as
591: labels, color, etc. The axis context should not be destroyed by the
592: application code.
594: Not Collective, axis is parallel if hist is parallel
596: Input Parameter:
597: . hist - The histogram context
599: Output Parameter:
600: . axis - The axis context
602: Level: intermediate
604: .seealso: `PetscDrawHG`, `PetscDrawAxis`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`, `PetscDrawAxis`, `PetscDrawHGSetLimits()`
605: @*/
606: PetscErrorCode PetscDrawHGGetAxis(PetscDrawHG hist, PetscDrawAxis *axis)
607: {
608: PetscFunctionBegin;
611: *axis = hist->axis;
612: PetscFunctionReturn(PETSC_SUCCESS);
613: }
615: /*@C
616: PetscDrawHGGetDraw - Gets the draw context associated with a histogram.
618: Not Collective, draw is parallel if hist is parallel
620: Input Parameter:
621: . hist - The histogram context
623: Output Parameter:
624: . draw - The draw context
626: Level: intermediate
628: .seealso: `PetscDraw`, `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`, `PetscDrawAxis`, `PetscDrawHGSetLimits()`
629: @*/
630: PetscErrorCode PetscDrawHGGetDraw(PetscDrawHG hist, PetscDraw *draw)
631: {
632: PetscFunctionBegin;
635: *draw = hist->win;
636: PetscFunctionReturn(PETSC_SUCCESS);
637: }