Actual source code: hists.c
1: /*
2: Contains the data structure for plotting a histogram in a window with an axis.
3: */
4: #include <petscdraw.h>
5: #include <petsc/private/petscimpl.h>
6: #include <petscviewer.h>
8: PetscClassId PETSC_DRAWHG_CLASSID = 0;
10: struct _p_PetscDrawHG {
11: PETSCHEADER(int);
12: PetscErrorCode (*destroy)(PetscDrawSP);
13: PetscErrorCode (*view)(PetscDrawSP, PetscViewer);
14: PetscDraw win;
15: PetscDrawAxis axis;
16: PetscReal xmin, xmax;
17: PetscReal ymin, ymax;
18: int numBins;
19: int maxBins;
20: PetscReal *bins;
21: int numValues;
22: int maxValues;
23: PetscReal *values;
24: int color;
25: PetscBool calcStats;
26: PetscBool integerBins;
27: };
29: #define CHUNKSIZE 100
31: /*@C
32: PetscDrawHGCreate - Creates a histogram data structure.
34: Collective
36: Input Parameters:
37: + draw - The window where the graph will be made
38: - bins - The number of bins to use
40: Output Parameter:
41: . hist - The histogram context
43: Level: intermediate
45: Notes:
46: The difference between a bar chart, `PetscDrawBar`, and a histogram, `PetscDrawHG`, is explained here <https://stattrek.com/statistics/charts/histogram.aspx?Tutorial=AP>
48: The histogram is only displayed when `PetscDrawHGDraw()` is called.
50: 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
51: zeroth MPI process in the communicator. All MPI processes in the communicator must call `PetscDrawHGDraw()` to display the updated graph.
53: .seealso: `PetscDrawHGDestroy()`, `PetscDrawHG`, `PetscDrawBarCreate()`, `PetscDrawBar`, `PetscDrawLGCreate()`, `PetscDrawLG`, `PetscDrawSPCreate()`, `PetscDrawSP`,
54: `PetscDrawHGSetNumberBins()`, `PetscDrawHGReset()`, `PetscDrawHGAddValue()`, `PetscDrawHGDraw()`, `PetscDrawHGSave()`, `PetscDrawHGView()`, `PetscDrawHGSetColor()`,
55: `PetscDrawHGSetLimits()`, `PetscDrawHGCalcStats()`, `PetscDrawHGIntegerBins()`, `PetscDrawHGGetAxis()`, `PetscDrawAxis`, `PetscDrawHGGetDraw()`
56: @*/
57: PetscErrorCode PetscDrawHGCreate(PetscDraw draw, int bins, PetscDrawHG *hist)
58: {
59: PetscDrawHG h;
61: PetscFunctionBegin;
64: PetscAssertPointer(hist, 3);
66: PetscCall(PetscHeaderCreate(h, PETSC_DRAWHG_CLASSID, "DrawHG", "Histogram", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawHGDestroy, NULL));
68: PetscCall(PetscObjectReference((PetscObject)draw));
69: h->win = draw;
71: h->view = NULL;
72: h->destroy = NULL;
73: h->color = PETSC_DRAW_GREEN;
74: h->xmin = PETSC_MAX_REAL;
75: h->xmax = PETSC_MIN_REAL;
76: h->ymin = 0.;
77: h->ymax = 1.;
78: h->numBins = bins;
79: h->maxBins = bins;
81: PetscCall(PetscMalloc1(h->maxBins, &h->bins));
83: h->numValues = 0;
84: h->maxValues = CHUNKSIZE;
85: h->calcStats = PETSC_FALSE;
86: h->integerBins = PETSC_FALSE;
88: PetscCall(PetscMalloc1(h->maxValues, &h->values));
89: PetscCall(PetscDrawAxisCreate(draw, &h->axis));
91: *hist = h;
92: PetscFunctionReturn(PETSC_SUCCESS);
93: }
95: /*@
96: PetscDrawHGSetNumberBins - Change the number of bins that are to be drawn in the histogram
98: Logically Collective
100: Input Parameters:
101: + hist - The histogram context.
102: - bins - The number of bins.
104: Level: intermediate
106: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGIntegerBins()`
107: @*/
108: PetscErrorCode PetscDrawHGSetNumberBins(PetscDrawHG hist, int bins)
109: {
110: PetscFunctionBegin;
114: if (hist->maxBins < bins) {
115: PetscCall(PetscFree(hist->bins));
116: PetscCall(PetscMalloc1(bins, &hist->bins));
117: hist->maxBins = bins;
118: }
119: hist->numBins = bins;
120: PetscFunctionReturn(PETSC_SUCCESS);
121: }
123: /*@
124: PetscDrawHGReset - Clears histogram to allow for reuse with new data.
126: Logically Collective
128: Input Parameter:
129: . hist - The histogram context.
131: Level: intermediate
133: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`
134: @*/
135: PetscErrorCode PetscDrawHGReset(PetscDrawHG hist)
136: {
137: PetscFunctionBegin;
140: hist->xmin = PETSC_MAX_REAL;
141: hist->xmax = PETSC_MIN_REAL;
142: hist->ymin = 0.0;
143: hist->ymax = 1.0;
144: hist->numValues = 0;
145: PetscFunctionReturn(PETSC_SUCCESS);
146: }
148: /*@C
149: PetscDrawHGDestroy - Frees all space taken up by histogram data structure.
151: Collective
153: Input Parameter:
154: . hist - The histogram context
156: Level: intermediate
158: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`
159: @*/
160: PetscErrorCode PetscDrawHGDestroy(PetscDrawHG *hist)
161: {
162: PetscFunctionBegin;
163: if (!*hist) PetscFunctionReturn(PETSC_SUCCESS);
165: if (--((PetscObject)*hist)->refct > 0) {
166: *hist = NULL;
167: PetscFunctionReturn(PETSC_SUCCESS);
168: }
170: PetscCall(PetscFree((*hist)->bins));
171: PetscCall(PetscFree((*hist)->values));
172: PetscCall(PetscDrawAxisDestroy(&(*hist)->axis));
173: PetscCall(PetscDrawDestroy(&(*hist)->win));
174: PetscCall(PetscHeaderDestroy(hist));
175: PetscFunctionReturn(PETSC_SUCCESS);
176: }
178: /*@
179: PetscDrawHGAddValue - Adds another value to the histogram.
181: Logically Collective
183: Input Parameters:
184: + hist - The histogram
185: - value - The value
187: Level: intermediate
189: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGReset()`
190: @*/
191: PetscErrorCode PetscDrawHGAddValue(PetscDrawHG hist, PetscReal value)
192: {
193: PetscFunctionBegin;
196: /* Allocate more memory if necessary */
197: if (hist->numValues >= hist->maxValues) {
198: PetscReal *tmp;
200: PetscCall(PetscMalloc1(hist->maxValues + CHUNKSIZE, &tmp));
201: PetscCall(PetscArraycpy(tmp, hist->values, hist->maxValues));
202: PetscCall(PetscFree(hist->values));
204: hist->values = tmp;
205: hist->maxValues += CHUNKSIZE;
206: }
207: /* I disagree with the original Petsc implementation here. There should be no overshoot, but rather the
208: stated convention of using half-open intervals (always the way to go) */
209: if (!hist->numValues && (hist->xmin == PETSC_MAX_REAL) && (hist->xmax == PETSC_MIN_REAL)) {
210: hist->xmin = value;
211: hist->xmax = value;
212: #if 1
213: } else {
214: /* Update limits */
215: if (value > hist->xmax) hist->xmax = value;
216: if (value < hist->xmin) hist->xmin = value;
217: #else
218: } else if (hist->numValues == 1) {
219: /* Update limits -- We need to overshoot the largest value somewhat */
220: if (value > hist->xmax) hist->xmax = value + 0.001 * (value - hist->xmin) / hist->numBins;
221: if (value < hist->xmin) {
222: hist->xmin = value;
223: hist->xmax = hist->xmax + 0.001 * (hist->xmax - hist->xmin) / hist->numBins;
224: }
225: } else {
226: /* Update limits -- We need to overshoot the largest value somewhat */
227: if (value > hist->xmax) hist->xmax = value + 0.001 * (hist->xmax - hist->xmin) / hist->numBins;
228: if (value < hist->xmin) hist->xmin = value;
229: #endif
230: }
232: hist->values[hist->numValues++] = value;
233: PetscFunctionReturn(PETSC_SUCCESS);
234: }
236: /*@
237: PetscDrawHGDraw - Redraws a histogram.
239: Collective
241: Input Parameter:
242: . hist - The histogram context
244: Level: intermediate
246: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGAddValue()`, `PetscDrawHGReset()`
247: @*/
248: PetscErrorCode PetscDrawHGDraw(PetscDrawHG hist)
249: {
250: PetscDraw draw;
251: PetscBool isnull;
252: PetscReal xmin, xmax, ymin, ymax, *bins, *values, binSize, binLeft, binRight, maxHeight, mean, var;
253: char title[256];
254: char xlabel[256];
255: PetscInt numBins, numBinsOld, numValues, initSize, i, p, bcolor, color;
256: PetscMPIInt rank;
258: PetscFunctionBegin;
260: PetscCall(PetscDrawIsNull(hist->win, &isnull));
261: if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
262: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)hist), &rank));
264: if ((hist->xmin >= hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(PETSC_SUCCESS);
265: if (hist->numValues < 1) PetscFunctionReturn(PETSC_SUCCESS);
267: color = hist->color;
268: if (color == PETSC_DRAW_ROTATE) bcolor = PETSC_DRAW_BLACK + 1;
269: else bcolor = color;
271: xmin = hist->xmin;
272: xmax = hist->xmax;
273: ymin = hist->ymin;
274: ymax = hist->ymax;
275: numValues = hist->numValues;
276: values = hist->values;
277: mean = 0.0;
278: var = 0.0;
280: draw = hist->win;
281: PetscCall(PetscDrawCheckResizedWindow(draw));
282: PetscCall(PetscDrawClear(draw));
284: if (xmin == xmax) {
285: /* Calculate number of points in each bin */
286: bins = hist->bins;
287: bins[0] = 0.;
288: for (p = 0; p < numValues; p++) {
289: if (values[p] == xmin) bins[0]++;
290: mean += values[p];
291: var += values[p] * values[p];
292: }
293: maxHeight = bins[0];
294: if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
295: xmax = xmin + 1;
296: PetscCall(PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax));
297: if (hist->calcStats) {
298: mean /= numValues;
299: if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1);
300: else var = 0.0;
301: PetscCall(PetscSNPrintf(title, 256, "Mean: %g Var: %g", (double)mean, (double)var));
302: PetscCall(PetscSNPrintf(xlabel, 256, "Total: %" PetscInt_FMT, numValues));
303: PetscCall(PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL));
304: }
305: PetscCall(PetscDrawAxisDraw(hist->axis));
306: PetscDrawCollectiveBegin(draw);
307: if (rank == 0) { /* Draw bins */
308: binLeft = xmin;
309: binRight = xmax;
310: PetscCall(PetscDrawRectangle(draw, binLeft, ymin, binRight, bins[0], bcolor, bcolor, bcolor, bcolor));
311: PetscCall(PetscDrawLine(draw, binLeft, ymin, binLeft, bins[0], PETSC_DRAW_BLACK));
312: PetscCall(PetscDrawLine(draw, binRight, ymin, binRight, bins[0], PETSC_DRAW_BLACK));
313: PetscCall(PetscDrawLine(draw, binLeft, bins[0], binRight, bins[0], PETSC_DRAW_BLACK));
314: }
315: PetscDrawCollectiveEnd(draw);
316: } else {
317: numBins = hist->numBins;
318: numBinsOld = hist->numBins;
319: if (hist->integerBins && (((int)xmax - xmin) + 1.0e-05 > xmax - xmin)) {
320: initSize = (int)((int)xmax - xmin) / numBins;
321: while (initSize * numBins != (int)xmax - xmin) {
322: initSize = PetscMax(initSize - 1, 1);
323: numBins = (int)((int)xmax - xmin) / initSize;
324: PetscCall(PetscDrawHGSetNumberBins(hist, numBins));
325: }
326: }
327: binSize = (xmax - xmin) / numBins;
328: bins = hist->bins;
330: PetscCall(PetscArrayzero(bins, numBins));
332: maxHeight = 0.0;
333: for (i = 0; i < numBins; i++) {
334: binLeft = xmin + binSize * i;
335: binRight = xmin + binSize * (i + 1);
336: for (p = 0; p < numValues; p++) {
337: if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
338: /* Handle last bin separately */
339: if ((i == numBins - 1) && (values[p] == binRight)) bins[i]++;
340: if (!i) {
341: mean += values[p];
342: var += values[p] * values[p];
343: }
344: }
345: maxHeight = PetscMax(maxHeight, bins[i]);
346: }
347: if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
349: PetscCall(PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax));
350: if (hist->calcStats) {
351: mean /= numValues;
352: if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1);
353: else var = 0.0;
354: PetscCall(PetscSNPrintf(title, 256, "Mean: %g Var: %g", (double)mean, (double)var));
355: PetscCall(PetscSNPrintf(xlabel, 256, "Total: %" PetscInt_FMT, numValues));
356: PetscCall(PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL));
357: }
358: PetscCall(PetscDrawAxisDraw(hist->axis));
359: PetscDrawCollectiveBegin(draw);
360: if (rank == 0) { /* Draw bins */
361: for (i = 0; i < numBins; i++) {
362: binLeft = xmin + binSize * i;
363: binRight = xmin + binSize * (i + 1);
364: PetscCall(PetscDrawRectangle(draw, binLeft, ymin, binRight, bins[i], bcolor, bcolor, bcolor, bcolor));
365: PetscCall(PetscDrawLine(draw, binLeft, ymin, binLeft, bins[i], PETSC_DRAW_BLACK));
366: PetscCall(PetscDrawLine(draw, binRight, ymin, binRight, bins[i], PETSC_DRAW_BLACK));
367: PetscCall(PetscDrawLine(draw, binLeft, bins[i], binRight, bins[i], PETSC_DRAW_BLACK));
368: if (color == PETSC_DRAW_ROTATE && bins[i]) bcolor++;
369: if (bcolor > PETSC_DRAW_BASIC_COLORS - 1) bcolor = PETSC_DRAW_BLACK + 1;
370: }
371: }
372: PetscDrawCollectiveEnd(draw);
373: PetscCall(PetscDrawHGSetNumberBins(hist, numBinsOld));
374: }
376: PetscCall(PetscDrawFlush(draw));
377: PetscCall(PetscDrawPause(draw));
378: PetscFunctionReturn(PETSC_SUCCESS);
379: }
381: /*@
382: PetscDrawHGSave - Saves a drawn image
384: Collective
386: Input Parameter:
387: . hg - The histogram context
389: Level: intermediate
391: .seealso: `PetscDrawSave()`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawHGDraw()`
392: @*/
393: PetscErrorCode PetscDrawHGSave(PetscDrawHG hg)
394: {
395: PetscFunctionBegin;
397: PetscCall(PetscDrawSave(hg->win));
398: PetscFunctionReturn(PETSC_SUCCESS);
399: }
401: /*@
402: PetscDrawHGView - Prints the histogram information to a viewer
404: Not Collective
406: Input Parameters:
407: + hist - The histogram context
408: - viewer - The viewer to view it with
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()`, `PetscDrawHGSetLimits()`
605: @*/
606: PetscErrorCode PetscDrawHGGetAxis(PetscDrawHG hist, PetscDrawAxis *axis)
607: {
608: PetscFunctionBegin;
610: PetscAssertPointer(axis, 2);
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;
634: PetscAssertPointer(draw, 2);
635: *draw = hist->win;
636: PetscFunctionReturn(PETSC_SUCCESS);
637: }