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)(xmax - xmin)) / numBins;
316: while (initSize * numBins != (int)xmax - xmin) {
317: initSize = PetscMax(initSize - 1, 1);
318: numBins = ((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;
413: int inumBins;
415: PetscFunctionBegin;
418: if ((hist->xmin > hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(PETSC_SUCCESS);
419: if (hist->numValues < 1) PetscFunctionReturn(PETSC_SUCCESS);
421: if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)hist), &viewer));
422: PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)hist, viewer));
423: xmax = hist->xmax;
424: xmin = hist->xmin;
425: numValues = hist->numValues;
426: values = hist->values;
427: mean = 0.0;
428: var = 0.0;
429: if (xmax == xmin) {
430: /* Calculate number of points in the bin */
431: bins = hist->bins;
432: bins[0] = 0.;
433: for (p = 0; p < numValues; p++) {
434: if (values[p] == xmin) bins[0]++;
435: mean += values[p];
436: var += values[p] * values[p];
437: }
438: /* Draw bins */
439: PetscCall(PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", 0, (double)xmin, (double)xmax, (double)bins[0]));
440: } else {
441: numBins = hist->numBins;
442: numBinsOld = hist->numBins;
443: if (hist->integerBins && (((int)xmax - xmin) + 1.0e-05 > xmax - xmin)) {
444: initSize = (int)((int)xmax - xmin) / numBins;
445: while (initSize * numBins != (int)xmax - xmin) {
446: initSize = PetscMax(initSize - 1, 1);
447: numBins = (int)((int)xmax - xmin) / initSize;
448: PetscCall(PetscCIntCast(numBins, &inumBins));
449: PetscCall(PetscDrawHGSetNumberBins(hist, inumBins));
450: }
451: }
452: binSize = (xmax - xmin) / numBins;
453: bins = hist->bins;
455: /* Calculate number of points in each bin */
456: PetscCall(PetscArrayzero(bins, numBins));
457: for (i = 0; i < numBins; i++) {
458: binLeft = xmin + binSize * i;
459: binRight = xmin + binSize * (i + 1);
460: for (p = 0; p < numValues; p++) {
461: if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
462: /* Handle last bin separately */
463: if ((i == numBins - 1) && (values[p] == binRight)) bins[i]++;
464: if (!i) {
465: mean += values[p];
466: var += values[p] * values[p];
467: }
468: }
469: }
470: /* Draw bins */
471: for (i = 0; i < numBins; i++) {
472: binLeft = xmin + binSize * i;
473: binRight = xmin + binSize * (i + 1);
474: PetscCall(PetscViewerASCIIPrintf(viewer, "Bin %2" PetscInt_FMT " (%6.2g - %6.2g): %.0g\n", i, (double)binLeft, (double)binRight, (double)bins[i]));
475: }
476: PetscCall(PetscCIntCast(numBinsOld, &inumBins));
477: PetscCall(PetscDrawHGSetNumberBins(hist, inumBins));
478: }
480: if (hist->calcStats) {
481: mean /= numValues;
482: if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1);
483: else var = 0.0;
484: PetscCall(PetscViewerASCIIPrintf(viewer, "Mean: %g Var: %g\n", (double)mean, (double)var));
485: PetscCall(PetscViewerASCIIPrintf(viewer, "Total: %" PetscInt_FMT "\n", numValues));
486: }
487: PetscFunctionReturn(PETSC_SUCCESS);
488: }
490: /*@
491: PetscDrawHGSetColor - Sets the color the bars will be drawn with.
493: Logically Collective
495: Input Parameters:
496: + hist - The histogram context
497: - color - one of the colors defined in petscdraw.h or `PETSC_DRAW_ROTATE` to make each bar a different color
499: Level: intermediate
501: .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`, `PetscDrawHGGetAxis()`
502: @*/
503: PetscErrorCode PetscDrawHGSetColor(PetscDrawHG hist, int color)
504: {
505: PetscFunctionBegin;
508: hist->color = color;
509: PetscFunctionReturn(PETSC_SUCCESS);
510: }
512: /*@
513: PetscDrawHGSetLimits - Sets the axis limits for a histogram. If more
514: points are added after this call, the limits will be adjusted to
515: include those additional points.
517: Logically Collective
519: Input Parameters:
520: + hist - The histogram context
521: . x_min - the horizontal lower limit
522: . x_max - the horizontal upper limit
523: . y_min - the vertical lower limit
524: - y_max - the vertical upper limit
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: /*@
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()`, `PetscDrawHGSetLimits()`
603: @*/
604: PetscErrorCode PetscDrawHGGetAxis(PetscDrawHG hist, PetscDrawAxis *axis)
605: {
606: PetscFunctionBegin;
608: PetscAssertPointer(axis, 2);
609: *axis = hist->axis;
610: PetscFunctionReturn(PETSC_SUCCESS);
611: }
613: /*@
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;
632: PetscAssertPointer(draw, 2);
633: *draw = hist->win;
634: PetscFunctionReturn(PETSC_SUCCESS);
635: }