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: /*@
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));
67: PetscCall(PetscObjectReference((PetscObject)draw));
68: h->win = draw;
69: h->view = NULL;
70: h->destroy = NULL;
71: h->color = PETSC_DRAW_GREEN;
72: h->xmin = PETSC_MAX_REAL;
73: h->xmax = PETSC_MIN_REAL;
74: h->ymin = 0.;
75: h->ymax = 1.;
76: h->numBins = bins;
77: h->maxBins = bins;
78: PetscCall(PetscMalloc1(h->maxBins, &h->bins));
79: h->numValues = 0;
80: h->maxValues = CHUNKSIZE;
81: h->calcStats = PETSC_FALSE;
82: h->integerBins = PETSC_FALSE;
83: PetscCall(PetscMalloc1(h->maxValues, &h->values));
84: PetscCall(PetscDrawAxisCreate(draw, &h->axis));
85: *hist = h;
86: PetscFunctionReturn(PETSC_SUCCESS);
87: }
89: /*@
90: PetscDrawHGSetNumberBins - Change the number of bins that are to be drawn in the histogram
92: Logically Collective
94: Input Parameters:
95: + hist - The histogram context.
96: - bins - The number of bins.
98: Level: intermediate
100: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGIntegerBins()`
101: @*/
102: PetscErrorCode PetscDrawHGSetNumberBins(PetscDrawHG hist, int bins)
103: {
104: PetscFunctionBegin;
108: if (hist->maxBins < bins) {
109: PetscCall(PetscFree(hist->bins));
110: PetscCall(PetscMalloc1(bins, &hist->bins));
111: hist->maxBins = bins;
112: }
113: hist->numBins = bins;
114: PetscFunctionReturn(PETSC_SUCCESS);
115: }
117: /*@
118: PetscDrawHGReset - Clears histogram to allow for reuse with new data.
120: Logically Collective
122: Input Parameter:
123: . hist - The histogram context.
125: Level: intermediate
127: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`
128: @*/
129: PetscErrorCode PetscDrawHGReset(PetscDrawHG hist)
130: {
131: PetscFunctionBegin;
134: hist->xmin = PETSC_MAX_REAL;
135: hist->xmax = PETSC_MIN_REAL;
136: hist->ymin = 0.0;
137: hist->ymax = 1.0;
138: hist->numValues = 0;
139: PetscFunctionReturn(PETSC_SUCCESS);
140: }
142: /*@
143: PetscDrawHGDestroy - Frees all space taken up by histogram data structure.
145: Collective
147: Input Parameter:
148: . hist - The histogram context
150: Level: intermediate
152: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`
153: @*/
154: PetscErrorCode PetscDrawHGDestroy(PetscDrawHG *hist)
155: {
156: PetscFunctionBegin;
157: if (!*hist) PetscFunctionReturn(PETSC_SUCCESS);
159: if (--((PetscObject)*hist)->refct > 0) {
160: *hist = NULL;
161: PetscFunctionReturn(PETSC_SUCCESS);
162: }
164: PetscCall(PetscFree((*hist)->bins));
165: PetscCall(PetscFree((*hist)->values));
166: PetscCall(PetscDrawAxisDestroy(&(*hist)->axis));
167: PetscCall(PetscDrawDestroy(&(*hist)->win));
168: PetscCall(PetscHeaderDestroy(hist));
169: PetscFunctionReturn(PETSC_SUCCESS);
170: }
172: /*@
173: PetscDrawHGAddValue - Adds another value to the histogram.
175: Logically Collective
177: Input Parameters:
178: + hist - The histogram
179: - value - The value
181: Level: intermediate
183: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGReset()`
184: @*/
185: PetscErrorCode PetscDrawHGAddValue(PetscDrawHG hist, PetscReal value)
186: {
187: PetscFunctionBegin;
190: /* Allocate more memory if necessary */
191: if (hist->numValues >= hist->maxValues) {
192: PetscReal *tmp;
194: PetscCall(PetscMalloc1(hist->maxValues + CHUNKSIZE, &tmp));
195: PetscCall(PetscArraycpy(tmp, hist->values, hist->maxValues));
196: PetscCall(PetscFree(hist->values));
198: hist->values = tmp;
199: hist->maxValues += CHUNKSIZE;
200: }
201: /* I disagree with the original Petsc implementation here. There should be no overshoot, but rather the
202: stated convention of using half-open intervals (always the way to go) */
203: if (!hist->numValues && (hist->xmin == PETSC_MAX_REAL) && (hist->xmax == PETSC_MIN_REAL)) {
204: hist->xmin = value;
205: hist->xmax = value;
206: #if 1
207: } else {
208: /* Update limits */
209: if (value > hist->xmax) hist->xmax = value;
210: if (value < hist->xmin) hist->xmin = value;
211: #else
212: } else if (hist->numValues == 1) {
213: /* Update limits -- We need to overshoot the largest value somewhat */
214: if (value > hist->xmax) hist->xmax = value + 0.001 * (value - hist->xmin) / (PetscReal)hist->numBins;
215: if (value < hist->xmin) {
216: hist->xmin = value;
217: hist->xmax = hist->xmax + 0.001 * (hist->xmax - hist->xmin) / (PetscReal)hist->numBins;
218: }
219: } else {
220: /* Update limits -- We need to overshoot the largest value somewhat */
221: if (value > hist->xmax) hist->xmax = value + 0.001 * (hist->xmax - hist->xmin) / (PetscReal)hist->numBins;
222: if (value < hist->xmin) hist->xmin = value;
223: #endif
224: }
226: hist->values[hist->numValues++] = value;
227: PetscFunctionReturn(PETSC_SUCCESS);
228: }
230: /*@
231: PetscDrawHGDraw - Redraws a histogram.
233: Collective
235: Input Parameter:
236: . hist - The histogram context
238: Level: intermediate
240: .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGAddValue()`, `PetscDrawHGReset()`
241: @*/
242: PetscErrorCode PetscDrawHGDraw(PetscDrawHG hist)
243: {
244: PetscDraw draw;
245: PetscBool isnull;
246: PetscReal xmin, xmax, ymin, ymax, *bins, *values, binSize, binLeft, binRight, maxHeight, mean, var;
247: char title[256];
248: char xlabel[256];
249: PetscInt numValues, initSize, i, p;
250: int bcolor, color, numBins, numBinsOld;
251: PetscMPIInt rank;
253: PetscFunctionBegin;
255: PetscCall(PetscDrawIsNull(hist->win, &isnull));
256: if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
257: PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)hist), &rank));
259: if ((hist->xmin >= hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(PETSC_SUCCESS);
260: if (hist->numValues < 1) PetscFunctionReturn(PETSC_SUCCESS);
262: color = hist->color;
263: if (color == PETSC_DRAW_ROTATE) bcolor = PETSC_DRAW_BLACK + 1;
264: else bcolor = color;
266: xmin = hist->xmin;
267: xmax = hist->xmax;
268: ymin = hist->ymin;
269: ymax = hist->ymax;
270: numValues = hist->numValues;
271: values = hist->values;
272: mean = 0.0;
273: var = 0.0;
275: draw = hist->win;
276: PetscCall(PetscDrawCheckResizedWindow(draw));
277: PetscCall(PetscDrawClear(draw));
279: if (xmin == xmax) {
280: /* Calculate number of points in each bin */
281: bins = hist->bins;
282: bins[0] = 0.;
283: for (p = 0; p < numValues; p++) {
284: if (values[p] == xmin) bins[0]++;
285: mean += values[p];
286: var += values[p] * values[p];
287: }
288: maxHeight = bins[0];
289: if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
290: xmax = xmin + 1;
291: PetscCall(PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax));
292: if (hist->calcStats) {
293: mean /= (PetscReal)numValues;
294: if (numValues > 1) var = (var - ((PetscReal)numValues) * mean * mean) / ((PetscReal)numValues - 1);
295: else var = 0.0;
296: PetscCall(PetscSNPrintf(title, 256, "Mean: %g Var: %g", (double)mean, (double)var));
297: PetscCall(PetscSNPrintf(xlabel, 256, "Total: %" PetscInt_FMT, numValues));
298: PetscCall(PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL));
299: }
300: PetscCall(PetscDrawAxisDraw(hist->axis));
301: PetscDrawCollectiveBegin(draw);
302: if (rank == 0) { /* Draw bins */
303: binLeft = xmin;
304: binRight = xmax;
305: PetscCall(PetscDrawRectangle(draw, binLeft, ymin, binRight, bins[0], bcolor, bcolor, bcolor, bcolor));
306: PetscCall(PetscDrawLine(draw, binLeft, ymin, binLeft, bins[0], PETSC_DRAW_BLACK));
307: PetscCall(PetscDrawLine(draw, binRight, ymin, binRight, bins[0], PETSC_DRAW_BLACK));
308: PetscCall(PetscDrawLine(draw, binLeft, bins[0], binRight, bins[0], PETSC_DRAW_BLACK));
309: }
310: PetscDrawCollectiveEnd(draw);
311: } else {
312: numBins = hist->numBins;
313: numBinsOld = hist->numBins;
314: if (hist->integerBins && (((int)xmax - xmin) + 1.0e-05 > xmax - xmin)) {
315: initSize = (int)((int)(xmax - xmin)) / numBins;
316: while (initSize * numBins != (int)xmax - xmin) {
317: initSize = PetscMax(initSize - 1, 1);
318: numBins = (int)((int)(xmax - xmin)) / initSize;
319: PetscCall(PetscDrawHGSetNumberBins(hist, numBins));
320: }
321: }
322: binSize = (xmax - xmin) / (PetscReal)numBins;
323: bins = hist->bins;
325: PetscCall(PetscArrayzero(bins, numBins));
327: maxHeight = 0.0;
328: for (i = 0; i < numBins; i++) {
329: binLeft = xmin + binSize * i;
330: binRight = xmin + binSize * (i + 1);
331: for (p = 0; p < numValues; p++) {
332: if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
333: /* Handle last bin separately */
334: if ((i == numBins - 1) && (values[p] == binRight)) bins[i]++;
335: if (!i) {
336: mean += values[p];
337: var += values[p] * values[p];
338: }
339: }
340: maxHeight = PetscMax(maxHeight, bins[i]);
341: }
342: if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
344: PetscCall(PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax));
345: if (hist->calcStats) {
346: mean /= numValues;
347: if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1);
348: else var = 0.0;
349: PetscCall(PetscSNPrintf(title, 256, "Mean: %g Var: %g", (double)mean, (double)var));
350: PetscCall(PetscSNPrintf(xlabel, 256, "Total: %" PetscInt_FMT, numValues));
351: PetscCall(PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL));
352: }
353: PetscCall(PetscDrawAxisDraw(hist->axis));
354: PetscDrawCollectiveBegin(draw);
355: if (rank == 0) { /* Draw bins */
356: for (i = 0; i < numBins; i++) {
357: binLeft = xmin + binSize * i;
358: binRight = xmin + binSize * (i + 1);
359: PetscCall(PetscDrawRectangle(draw, binLeft, ymin, binRight, bins[i], bcolor, bcolor, bcolor, bcolor));
360: PetscCall(PetscDrawLine(draw, binLeft, ymin, binLeft, bins[i], PETSC_DRAW_BLACK));
361: PetscCall(PetscDrawLine(draw, binRight, ymin, binRight, bins[i], PETSC_DRAW_BLACK));
362: PetscCall(PetscDrawLine(draw, binLeft, bins[i], binRight, bins[i], PETSC_DRAW_BLACK));
363: if (color == PETSC_DRAW_ROTATE && bins[i]) bcolor++;
364: if (bcolor > PETSC_DRAW_BASIC_COLORS - 1) bcolor = PETSC_DRAW_BLACK + 1;
365: }
366: }
367: PetscDrawCollectiveEnd(draw);
368: PetscCall(PetscDrawHGSetNumberBins(hist, numBinsOld));
369: }
371: PetscCall(PetscDrawFlush(draw));
372: PetscCall(PetscDrawPause(draw));
373: PetscFunctionReturn(PETSC_SUCCESS);
374: }
376: /*@
377: PetscDrawHGSave - Saves a drawn image
379: Collective
381: Input Parameter:
382: . hg - The histogram context
384: Level: intermediate
386: .seealso: `PetscDrawSave()`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawHGDraw()`
387: @*/
388: PetscErrorCode PetscDrawHGSave(PetscDrawHG hg)
389: {
390: PetscFunctionBegin;
392: PetscCall(PetscDrawSave(hg->win));
393: PetscFunctionReturn(PETSC_SUCCESS);
394: }
396: /*@
397: PetscDrawHGView - Prints the histogram information to a viewer
399: Not Collective
401: Input Parameters:
402: + hist - The histogram context
403: - viewer - The viewer to view it with
405: Level: beginner
407: .seealso: `PetscDrawHG`, `PetscViewer`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`
408: @*/
409: PetscErrorCode PetscDrawHGView(PetscDrawHG hist, PetscViewer viewer)
410: {
411: PetscReal xmax, xmin, *bins, *values, binSize, binLeft, binRight, mean, var;
412: PetscInt numBins, numBinsOld, numValues, initSize, i, p;
414: PetscFunctionBegin;
417: if ((hist->xmin > hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(PETSC_SUCCESS);
418: if (hist->numValues < 1) PetscFunctionReturn(PETSC_SUCCESS);
420: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)hist), &viewer));
421: PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)hist, viewer));
422: xmax = hist->xmax;
423: xmin = hist->xmin;
424: numValues = hist->numValues;
425: values = hist->values;
426: mean = 0.0;
427: var = 0.0;
428: if (xmax == xmin) {
429: /* Calculate number of points in the bin */
430: bins = hist->bins;
431: bins[0] = 0.;
432: for (p = 0; p < numValues; p++) {
433: if (values[p] == xmin) bins[0]++;
434: mean += values[p];
435: var += values[p] * values[p];
436: }
437: /* Draw bins */
438: PetscCall(PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", 0, (double)xmin, (double)xmax, (double)bins[0]));
439: } else {
440: numBins = hist->numBins;
441: numBinsOld = hist->numBins;
442: if (hist->integerBins && (((int)xmax - xmin) + 1.0e-05 > xmax - xmin)) {
443: initSize = (int)((int)xmax - xmin) / numBins;
444: while (initSize * numBins != (int)xmax - xmin) {
445: initSize = PetscMax(initSize - 1, 1);
446: numBins = (int)((int)xmax - xmin) / initSize;
447: PetscCall(PetscDrawHGSetNumberBins(hist, (int)numBins));
448: }
449: }
450: binSize = (xmax - xmin) / numBins;
451: bins = hist->bins;
453: /* Calculate number of points in each bin */
454: PetscCall(PetscArrayzero(bins, numBins));
455: for (i = 0; i < numBins; i++) {
456: binLeft = xmin + binSize * i;
457: binRight = xmin + binSize * (i + 1);
458: for (p = 0; p < numValues; p++) {
459: if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
460: /* Handle last bin separately */
461: if ((i == numBins - 1) && (values[p] == binRight)) bins[i]++;
462: if (!i) {
463: mean += values[p];
464: var += values[p] * values[p];
465: }
466: }
467: }
468: /* Draw bins */
469: for (i = 0; i < numBins; i++) {
470: binLeft = xmin + binSize * i;
471: binRight = xmin + binSize * (i + 1);
472: PetscCall(PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", (int)i, (double)binLeft, (double)binRight, (double)bins[i]));
473: }
474: PetscCall(PetscDrawHGSetNumberBins(hist, (int)numBinsOld));
475: }
477: if (hist->calcStats) {
478: mean /= numValues;
479: if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1);
480: else var = 0.0;
481: PetscCall(PetscViewerASCIIPrintf(viewer, "Mean: %g Var: %g\n", (double)mean, (double)var));
482: PetscCall(PetscViewerASCIIPrintf(viewer, "Total: %" PetscInt_FMT "\n", numValues));
483: }
484: PetscFunctionReturn(PETSC_SUCCESS);
485: }
487: /*@
488: PetscDrawHGSetColor - Sets the color the bars will be drawn with.
490: Logically Collective
492: Input Parameters:
493: + hist - The histogram context
494: - color - one of the colors defined in petscdraw.h or `PETSC_DRAW_ROTATE` to make each bar a different color
496: Level: intermediate
498: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`, `PetscDrawHGGetAxis()`
499: @*/
500: PetscErrorCode PetscDrawHGSetColor(PetscDrawHG hist, int color)
501: {
502: PetscFunctionBegin;
505: hist->color = color;
506: PetscFunctionReturn(PETSC_SUCCESS);
507: }
509: /*@
510: PetscDrawHGSetLimits - Sets the axis limits for a histogram. If more
511: points are added after this call, the limits will be adjusted to
512: include those additional points.
514: Logically Collective
516: Input Parameters:
517: + hist - The histogram context
518: . x_min - the horizontal lower limit
519: . x_max - the horizontal upper limit
520: . y_min - the vertical lower limit
521: - y_max - the vertical upper limit
523: Level: intermediate
525: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`, `PetscDrawHGGetAxis()`
526: @*/
527: PetscErrorCode PetscDrawHGSetLimits(PetscDrawHG hist, PetscReal x_min, PetscReal x_max, int y_min, int y_max)
528: {
529: PetscFunctionBegin;
532: hist->xmin = x_min;
533: hist->xmax = x_max;
534: hist->ymin = y_min;
535: hist->ymax = y_max;
536: PetscFunctionReturn(PETSC_SUCCESS);
537: }
539: /*@
540: PetscDrawHGCalcStats - Turns on calculation of descriptive statistics associated with the histogram
542: Not Collective
544: Input Parameters:
545: + hist - The histogram context
546: - calc - Flag for calculation
548: Level: intermediate
550: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`
551: @*/
552: PetscErrorCode PetscDrawHGCalcStats(PetscDrawHG hist, PetscBool calc)
553: {
554: PetscFunctionBegin;
557: hist->calcStats = calc;
558: PetscFunctionReturn(PETSC_SUCCESS);
559: }
561: /*@
562: PetscDrawHGIntegerBins - Turns on integer width bins
564: Not Collective
566: Input Parameters:
567: + hist - The histogram context
568: - ints - Flag for integer width bins
570: Level: intermediate
572: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`
573: @*/
574: PetscErrorCode PetscDrawHGIntegerBins(PetscDrawHG hist, PetscBool ints)
575: {
576: PetscFunctionBegin;
579: hist->integerBins = ints;
580: PetscFunctionReturn(PETSC_SUCCESS);
581: }
583: /*@
584: PetscDrawHGGetAxis - Gets the axis context associated with a histogram.
585: This is useful if one wants to change some axis property, such as
586: labels, color, etc. The axis context should not be destroyed by the
587: application code.
589: Not Collective, axis is parallel if hist is parallel
591: Input Parameter:
592: . hist - The histogram context
594: Output Parameter:
595: . axis - The axis context
597: Level: intermediate
599: .seealso: `PetscDrawHG`, `PetscDrawAxis`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`, `PetscDrawHGSetLimits()`
600: @*/
601: PetscErrorCode PetscDrawHGGetAxis(PetscDrawHG hist, PetscDrawAxis *axis)
602: {
603: PetscFunctionBegin;
605: PetscAssertPointer(axis, 2);
606: *axis = hist->axis;
607: PetscFunctionReturn(PETSC_SUCCESS);
608: }
610: /*@
611: PetscDrawHGGetDraw - Gets the draw context associated with a histogram.
613: Not Collective, draw is parallel if hist is parallel
615: Input Parameter:
616: . hist - The histogram context
618: Output Parameter:
619: . draw - The draw context
621: Level: intermediate
623: .seealso: `PetscDraw`, `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`, `PetscDrawAxis`, `PetscDrawHGSetLimits()`
624: @*/
625: PetscErrorCode PetscDrawHGGetDraw(PetscDrawHG hist, PetscDraw *draw)
626: {
627: PetscFunctionBegin;
629: PetscAssertPointer(draw, 2);
630: *draw = hist->win;
631: PetscFunctionReturn(PETSC_SUCCESS);
632: }