1 2 /* 3 Contains the data structure for plotting a histogram in a window with an axis. 4 */ 5 #include <petscdraw.h> /*I "petscdraw.h" I*/ 6 #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 7 #include <petscviewer.h> /*I "petscviewer.h" I*/ 8 9 PetscClassId PETSC_DRAWHG_CLASSID = 0; 10 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 }; 29 30 #define CHUNKSIZE 100 31 32 /*@C 33 PetscDrawHGCreate - Creates a histogram data structure. 34 35 Collective on draw 36 37 Input Parameters: 38 + draw - The window where the graph will be made 39 - bins - The number of bins to use 40 41 Output Parameters: 42 . hist - The histogram context 43 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 46 47 The histogram is only displayed when `PetscDrawHGDraw()` is called. 48 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. 51 52 Level: intermediate 53 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 PetscDrawHG h; 60 61 PetscFunctionBegin; 62 PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 63 PetscValidLogicalCollectiveInt(draw, bins, 2); 64 PetscValidPointer(hist, 3); 65 66 PetscCall(PetscHeaderCreate(h, PETSC_DRAWHG_CLASSID, "DrawHG", "Histogram", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawHGDestroy, NULL)); 67 PetscCall(PetscLogObjectParent((PetscObject)draw, (PetscObject)h)); 68 69 PetscCall(PetscObjectReference((PetscObject)draw)); 70 h->win = draw; 71 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; 81 82 PetscCall(PetscMalloc1(h->maxBins, &h->bins)); 83 84 h->numValues = 0; 85 h->maxValues = CHUNKSIZE; 86 h->calcStats = PETSC_FALSE; 87 h->integerBins = PETSC_FALSE; 88 89 PetscCall(PetscMalloc1(h->maxValues, &h->values)); 90 PetscCall(PetscLogObjectMemory((PetscObject)h, (h->maxBins + h->maxValues) * sizeof(PetscReal))); 91 92 PetscCall(PetscDrawAxisCreate(draw, &h->axis)); 93 PetscCall(PetscLogObjectParent((PetscObject)h, (PetscObject)h->axis)); 94 95 *hist = h; 96 PetscFunctionReturn(0); 97 } 98 99 /*@ 100 PetscDrawHGSetNumberBins - Change the number of bins that are to be drawn in the histogram 101 102 Logically Collective on hist 103 104 Input Parameters: 105 + hist - The histogram context. 106 - bins - The number of bins. 107 108 Level: intermediate 109 110 .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGIntegerBins()` 111 @*/ 112 PetscErrorCode PetscDrawHGSetNumberBins(PetscDrawHG hist, int bins) { 113 PetscFunctionBegin; 114 PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 115 PetscValidLogicalCollectiveInt(hist, bins, 2); 116 117 if (hist->maxBins < bins) { 118 PetscCall(PetscFree(hist->bins)); 119 PetscCall(PetscMalloc1(bins, &hist->bins)); 120 PetscCall(PetscLogObjectMemory((PetscObject)hist, (bins - hist->maxBins) * sizeof(PetscReal))); 121 hist->maxBins = bins; 122 } 123 hist->numBins = bins; 124 PetscFunctionReturn(0); 125 } 126 127 /*@ 128 PetscDrawHGReset - Clears histogram to allow for reuse with new data. 129 130 Logically Collective on hist 131 132 Input Parameter: 133 . hist - The histogram context. 134 135 Level: intermediate 136 137 .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()` 138 @*/ 139 PetscErrorCode PetscDrawHGReset(PetscDrawHG hist) { 140 PetscFunctionBegin; 141 PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 142 143 hist->xmin = PETSC_MAX_REAL; 144 hist->xmax = PETSC_MIN_REAL; 145 hist->ymin = 0.0; 146 hist->ymax = 0.0; 147 hist->numValues = 0; 148 PetscFunctionReturn(0); 149 } 150 151 /*@C 152 PetscDrawHGDestroy - Frees all space taken up by histogram data structure. 153 154 Collective on hist 155 156 Input Parameter: 157 . hist - The histogram context 158 159 Level: intermediate 160 161 .seealso: `PetscDrawHGCreate()`, `PetscDrawHG` 162 @*/ 163 PetscErrorCode PetscDrawHGDestroy(PetscDrawHG *hist) { 164 PetscFunctionBegin; 165 if (!*hist) PetscFunctionReturn(0); 166 PetscValidHeaderSpecific(*hist, PETSC_DRAWHG_CLASSID, 1); 167 if (--((PetscObject)(*hist))->refct > 0) { 168 *hist = NULL; 169 PetscFunctionReturn(0); 170 } 171 172 PetscCall(PetscFree((*hist)->bins)); 173 PetscCall(PetscFree((*hist)->values)); 174 PetscCall(PetscDrawAxisDestroy(&(*hist)->axis)); 175 PetscCall(PetscDrawDestroy(&(*hist)->win)); 176 PetscCall(PetscHeaderDestroy(hist)); 177 PetscFunctionReturn(0); 178 } 179 180 /*@ 181 PetscDrawHGAddValue - Adds another value to the histogram. 182 183 Logically Collective on hist 184 185 Input Parameters: 186 + hist - The histogram 187 - value - The value 188 189 Level: intermediate 190 191 .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`, `PetscDrawHGReset()` 192 @*/ 193 PetscErrorCode PetscDrawHGAddValue(PetscDrawHG hist, PetscReal value) { 194 PetscFunctionBegin; 195 PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 196 197 /* Allocate more memory if necessary */ 198 if (hist->numValues >= hist->maxValues) { 199 PetscReal *tmp; 200 201 PetscCall(PetscMalloc1(hist->maxValues + CHUNKSIZE, &tmp)); 202 PetscCall(PetscLogObjectMemory((PetscObject)hist, CHUNKSIZE * sizeof(PetscReal))); 203 PetscCall(PetscArraycpy(tmp, hist->values, hist->maxValues)); 204 PetscCall(PetscFree(hist->values)); 205 206 hist->values = tmp; 207 hist->maxValues += CHUNKSIZE; 208 } 209 /* I disagree with the original Petsc implementation here. There should be no overshoot, but rather the 210 stated convention of using half-open intervals (always the way to go) */ 211 if (!hist->numValues && (hist->xmin == PETSC_MAX_REAL) && (hist->xmax == PETSC_MIN_REAL)) { 212 hist->xmin = value; 213 hist->xmax = value; 214 #if 1 215 } else { 216 /* Update limits */ 217 if (value > hist->xmax) hist->xmax = value; 218 if (value < hist->xmin) hist->xmin = value; 219 #else 220 } else if (hist->numValues == 1) { 221 /* Update limits -- We need to overshoot the largest value somewhat */ 222 if (value > hist->xmax) hist->xmax = value + 0.001 * (value - hist->xmin) / hist->numBins; 223 if (value < hist->xmin) { 224 hist->xmin = value; 225 hist->xmax = hist->xmax + 0.001 * (hist->xmax - hist->xmin) / hist->numBins; 226 } 227 } else { 228 /* Update limits -- We need to overshoot the largest value somewhat */ 229 if (value > hist->xmax) hist->xmax = value + 0.001 * (hist->xmax - hist->xmin) / hist->numBins; 230 if (value < hist->xmin) hist->xmin = value; 231 #endif 232 } 233 234 hist->values[hist->numValues++] = value; 235 PetscFunctionReturn(0); 236 } 237 238 /*@ 239 PetscDrawHGDraw - Redraws a histogram. 240 241 Collective on hist 242 243 Input Parameter: 244 . hist - The histogram context 245 246 Level: intermediate 247 248 .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`, `PetscDrawHGReset()` 249 @*/ 250 PetscErrorCode PetscDrawHGDraw(PetscDrawHG hist) { 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; 258 259 PetscFunctionBegin; 260 PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 261 PetscCall(PetscDrawIsNull(hist->win, &isnull)); 262 if (isnull) PetscFunctionReturn(0); 263 PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)hist), &rank)); 264 265 if ((hist->xmin >= hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(0); 266 if (hist->numValues < 1) PetscFunctionReturn(0); 267 268 color = hist->color; 269 if (color == PETSC_DRAW_ROTATE) bcolor = PETSC_DRAW_BLACK + 1; 270 else bcolor = color; 271 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; 280 281 draw = hist->win; 282 PetscCall(PetscDrawCheckResizedWindow(draw)); 283 PetscCall(PetscDrawClear(draw)); 284 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; 330 331 PetscCall(PetscArrayzero(bins, numBins)); 332 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; 349 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 } 376 377 PetscCall(PetscDrawFlush(draw)); 378 PetscCall(PetscDrawPause(draw)); 379 PetscFunctionReturn(0); 380 } 381 382 /*@ 383 PetscDrawHGSave - Saves a drawn image 384 385 Collective on hg 386 387 Input Parameter: 388 . hist - The histogram context 389 390 Level: intermediate 391 392 .seealso: `PetscDrawSave()`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()` 393 @*/ 394 PetscErrorCode PetscDrawHGSave(PetscDrawHG hg) { 395 PetscFunctionBegin; 396 PetscValidHeaderSpecific(hg, PETSC_DRAWHG_CLASSID, 1); 397 PetscCall(PetscDrawSave(hg->win)); 398 PetscFunctionReturn(0); 399 } 400 401 /*@ 402 PetscDrawHGView - Prints the histogram information to a viewer 403 404 Not collective 405 406 Input Parameter: 407 . hist - The histogram context 408 409 Level: beginner 410 411 .seealso: `PetscDrawHG`, `PetscViewer`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()` 412 @*/ 413 PetscErrorCode PetscDrawHGView(PetscDrawHG hist, PetscViewer viewer) { 414 PetscReal xmax, xmin, *bins, *values, binSize, binLeft, binRight, mean, var; 415 PetscInt numBins, numBinsOld, numValues, initSize, i, p; 416 417 PetscFunctionBegin; 418 PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 419 420 if ((hist->xmin > hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(0); 421 if (hist->numValues < 1) PetscFunctionReturn(0); 422 423 if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)hist), &viewer)); 424 PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)hist, viewer)); 425 xmax = hist->xmax; 426 xmin = hist->xmin; 427 numValues = hist->numValues; 428 values = hist->values; 429 mean = 0.0; 430 var = 0.0; 431 if (xmax == xmin) { 432 /* Calculate number of points in the bin */ 433 bins = hist->bins; 434 bins[0] = 0.; 435 for (p = 0; p < numValues; p++) { 436 if (values[p] == xmin) bins[0]++; 437 mean += values[p]; 438 var += values[p] * values[p]; 439 } 440 /* Draw bins */ 441 PetscCall(PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", 0, (double)xmin, (double)xmax, (double)bins[0])); 442 } else { 443 numBins = hist->numBins; 444 numBinsOld = hist->numBins; 445 if (hist->integerBins && (((int)xmax - xmin) + 1.0e-05 > xmax - xmin)) { 446 initSize = (int)((int)xmax - xmin) / numBins; 447 while (initSize * numBins != (int)xmax - xmin) { 448 initSize = PetscMax(initSize - 1, 1); 449 numBins = (int)((int)xmax - xmin) / initSize; 450 PetscCall(PetscDrawHGSetNumberBins(hist, numBins)); 451 } 452 } 453 binSize = (xmax - xmin) / numBins; 454 bins = hist->bins; 455 456 /* Calculate number of points in each bin */ 457 PetscCall(PetscArrayzero(bins, numBins)); 458 for (i = 0; i < numBins; i++) { 459 binLeft = xmin + binSize * i; 460 binRight = xmin + binSize * (i + 1); 461 for (p = 0; p < numValues; p++) { 462 if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++; 463 /* Handle last bin separately */ 464 if ((i == numBins - 1) && (values[p] == binRight)) bins[i]++; 465 if (!i) { 466 mean += values[p]; 467 var += values[p] * values[p]; 468 } 469 } 470 } 471 /* Draw bins */ 472 for (i = 0; i < numBins; i++) { 473 binLeft = xmin + binSize * i; 474 binRight = xmin + binSize * (i + 1); 475 PetscCall(PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", (int)i, (double)binLeft, (double)binRight, (double)bins[i])); 476 } 477 PetscCall(PetscDrawHGSetNumberBins(hist, numBinsOld)); 478 } 479 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(0); 488 } 489 490 /*@ 491 PetscDrawHGSetColor - Sets the color the bars will be drawn with. 492 493 Logically Collective on hist 494 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 498 different color 499 500 Level: intermediate 501 502 .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`, `PetscDrawHGGetAxis()` 503 @*/ 504 PetscErrorCode PetscDrawHGSetColor(PetscDrawHG hist, int color) { 505 PetscFunctionBegin; 506 PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 507 508 hist->color = color; 509 PetscFunctionReturn(0); 510 } 511 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. 516 517 Logically Collective on hist 518 519 Input Parameters: 520 + hist - The histogram context 521 - x_min,x_max,y_min,y_max - The limits 522 523 Level: intermediate 524 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 PetscFunctionBegin; 529 PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 530 531 hist->xmin = x_min; 532 hist->xmax = x_max; 533 hist->ymin = y_min; 534 hist->ymax = y_max; 535 PetscFunctionReturn(0); 536 } 537 538 /*@ 539 PetscDrawHGCalcStats - Turns on calculation of descriptive statistics associated with the histogram 540 541 Not collective 542 543 Input Parameters: 544 + hist - The histogram context 545 - calc - Flag for calculation 546 547 Level: intermediate 548 549 .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()` 550 @*/ 551 PetscErrorCode PetscDrawHGCalcStats(PetscDrawHG hist, PetscBool calc) { 552 PetscFunctionBegin; 553 PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 554 555 hist->calcStats = calc; 556 PetscFunctionReturn(0); 557 } 558 559 /*@ 560 PetscDrawHGIntegerBins - Turns on integer width bins 561 562 Not collective 563 564 Input Parameters: 565 + hist - The histogram context 566 - ints - Flag for integer width bins 567 568 Level: intermediate 569 570 .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()` 571 @*/ 572 PetscErrorCode PetscDrawHGIntegerBins(PetscDrawHG hist, PetscBool ints) { 573 PetscFunctionBegin; 574 PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 575 576 hist->integerBins = ints; 577 PetscFunctionReturn(0); 578 } 579 580 /*@C 581 PetscDrawHGGetAxis - Gets the axis context associated with a histogram. 582 This is useful if one wants to change some axis property, such as 583 labels, color, etc. The axis context should not be destroyed by the 584 application code. 585 586 Not Collective, axis is parallel if hist is parallel 587 588 Input Parameter: 589 . hist - The histogram context 590 591 Output Parameter: 592 . axis - The axis context 593 594 Level: intermediate 595 596 .seealso: `PetscDrawHG`, `PetscDrawAxis`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`, `PetscDrawAxis`, `PetscDrawHGSetLimits()` 597 @*/ 598 PetscErrorCode PetscDrawHGGetAxis(PetscDrawHG hist, PetscDrawAxis *axis) { 599 PetscFunctionBegin; 600 PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 601 PetscValidPointer(axis, 2); 602 *axis = hist->axis; 603 PetscFunctionReturn(0); 604 } 605 606 /*@C 607 PetscDrawHGGetDraw - Gets the draw context associated with a histogram. 608 609 Not Collective, draw is parallel if hist is parallel 610 611 Input Parameter: 612 . hist - The histogram context 613 614 Output Parameter: 615 . draw - The draw context 616 617 Level: intermediate 618 619 .seealso: `PetscDraw`, `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`, `PetscDrawAxis`, `PetscDrawHGSetLimits()` 620 @*/ 621 PetscErrorCode PetscDrawHGGetDraw(PetscDrawHG hist, PetscDraw *draw) { 622 PetscFunctionBegin; 623 PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 624 PetscValidPointer(draw, 2); 625 *draw = hist->win; 626 PetscFunctionReturn(0); 627 } 628