|
17 | 17 | import json
|
18 | 18 | import copy
|
19 | 19 | import matplotlib.pyplot as plt
|
| 20 | +from matplotlib.backends.backend_agg import FigureCanvasAgg |
| 21 | +import io |
20 | 22 |
|
21 | 23 | timezone = 'America/Vancouver'
|
22 | 24 |
|
@@ -462,67 +464,129 @@ def __init__(self,fileBundles: dict,epochSize=5, qualityCutoffFilter=0.95, debug
|
462 | 464 | sum += len(self.fileBundleSummeries[x])
|
463 | 465 | else:
|
464 | 466 | raise Exception("Invalid bundleType")
|
465 |
| - |
466 | 467 |
|
467 |
| - # Generates histogram on epochs average powerband values for inspection of distrobutions |
468 |
| - def distributionVetting(self): |
| 468 | + # generate file bundle stats |
| 469 | + self.computeFileBundleStats() |
| 470 | + |
| 471 | + def computeFileBundleStats(self): |
| 472 | + # Generates a dictionary of all the powerband values for epochs in recording groups |
469 | 473 | self.accumulatedPowerBands = {x:dict() for x in self.fileBundles}
|
470 | 474 | for x in self.fileBundles: # Basic sanity checks of distributions
|
471 | 475 | for y in self.fileBundleSummeries[x]:
|
472 | 476 | for epoch in y:
|
473 | 477 | for band in y[epoch]["avg_power_by_band"]:
|
474 | 478 | if band not in self.accumulatedPowerBands [x]: self.accumulatedPowerBands [x][band] = []
|
475 | 479 | self.accumulatedPowerBands [x][band].append(y[epoch]["avg_power_by_band"][band])
|
| 480 | + |
| 481 | + self.accumulatedPowerBandStats = {x:dict() for x in self.fileBundles} |
| 482 | + self.accumulatedPowerBandErrors = {x:dict() for x in self.fileBundles} |
476 | 483 |
|
477 |
| - |
478 |
| - count = 0 |
479 |
| - for band in bands_ordered: |
480 |
| - count+=1 |
481 |
| - for x in self.fileBundles: |
482 |
| - plt.subplot(5, 1, count) |
483 |
| - plt.hist(self.accumulatedPowerBands [x][band],alpha=0.5,bins=160,label=x) |
484 |
| - |
485 |
| - plt.title(f'{band} Epoch Averages') |
| 484 | + for x in self.accumulatedPowerBands: # avgs with error bars |
| 485 | + for band in self.accumulatedPowerBands[x]: |
| 486 | + self.accumulatedPowerBandStats[x][band] = np.nanmean(np.array(self.accumulatedPowerBands[x][band])) |
| 487 | + # print(np.array(accumulatedPowerBands[x][band])) |
| 488 | + self.accumulatedPowerBandErrors[x][band] = np.nanstd(np.array(self.accumulatedPowerBands[x][band])) * 2 |
486 | 489 |
|
487 |
| - plt.legend() |
488 |
| - plt.xlabel('uV') |
489 |
| - plt.ylabel('Count') |
490 |
| - plt.grid(True) |
491 |
| - plt.show() |
492 | 490 |
|
| 491 | + # Generates histogram on epochs average powerband values for inspection of distrobutions |
| 492 | + def distributionVetting(self, returnAsImageArray=False): |
493 | 493 |
|
494 |
| - # basic bar chart of powerbybands comparing between catergories with error bars encompassing 95% confidence interval assuming normal distrobutions |
495 |
| - def basicComparisons(self): |
496 |
| - accumatedPowerBandStats = {x:dict() for x in self.fileBundles} |
497 |
| - accumatedPowerBandErrors = {x:dict() for x in self.fileBundles} |
| 494 | + if returnAsImageArray: |
| 495 | + plt.switch_backend('Agg') |
498 | 496 |
|
499 |
| - for x in self.accumulatedPowerBands: # avgs with error bars |
500 |
| - for band in self.accumulatedPowerBands[x]: |
501 |
| - accumatedPowerBandStats[x][band] = np.nanmean(np.array(self.accumulatedPowerBands[x][band])) |
502 |
| - # print(np.array(accumulatedPowerBands[x][band])) |
503 |
| - accumatedPowerBandErrors[x][band] = np.nanstd(np.array(self.accumulatedPowerBands[x][band])) * 2 |
| 497 | + num_bands = len(bands_ordered) |
| 498 | + num_files = len(self.fileBundles) |
504 | 499 |
|
| 500 | + fig, axes = plt.subplots(num_bands, 1, figsize=(8, 6 * num_bands)) |
505 | 501 |
|
| 502 | + for count, band in enumerate(bands_ordered): |
| 503 | + ax = axes[count] |
| 504 | + for x in self.fileBundles: |
| 505 | + ax.hist(self.accumulatedPowerBands[x][band], alpha=0.5, bins=160, label=x) |
| 506 | + |
| 507 | + ax.set_title(f'{band} Epoch Averages') |
| 508 | + ax.legend() |
| 509 | + ax.set_xlabel('uV') |
| 510 | + ax.set_ylabel('Count') |
| 511 | + ax.grid(True) |
506 | 512 |
|
507 |
| - fig, ax = plt.subplots() |
508 |
| - bar_width = .3 |
509 |
| - currentBarDist = bar_width |
510 |
| - figs = {x:0 for x in self.fileBundles} |
511 |
| - index = np.arange(5) |
512 |
| - for x in accumatedPowerBandStats: |
513 |
| - print(x,accumatedPowerBandStats[x]) |
514 |
| - ax.bar(index+currentBarDist,list(accumatedPowerBandStats[x].values()), bar_width, |
515 |
| - label=x,yerr=list(accumatedPowerBandErrors[x].values())) |
516 |
| - currentBarDist+=bar_width |
517 |
| - |
518 |
| - ax.set_xticks(index + bar_width / 2) |
519 |
| - ax.set_xticklabels(accumatedPowerBandStats[x].keys()) |
520 |
| - ax.set_xlabel('Band') |
521 |
| - ax.set_ylabel('Average uV') |
522 |
| - ax.set_title('Average uV by Band') |
523 |
| - ax.legend() |
524 |
| - |
525 |
| - plt.show() |
| 513 | + # Render the figure to an Agg backend (image buffer) |
| 514 | + canvas = FigureCanvasAgg(fig) |
| 515 | + canvas.draw() |
| 516 | + |
| 517 | + # Convert the Agg buffer to a NumPy array |
| 518 | + img_data = np.frombuffer(canvas.tostring_rgb(), dtype='uint8') |
| 519 | + img_data = img_data.reshape(fig.canvas.get_width_height()[::-1] + (3,)) |
| 520 | + |
| 521 | + return img_data |
| 522 | + else: |
| 523 | + count = 0 |
| 524 | + for band in bands_ordered: |
| 525 | + count+=1 |
| 526 | + for x in self.fileBundles: |
| 527 | + plt.subplot(5, 1, count) |
| 528 | + plt.hist(self.accumulatedPowerBands [x][band],alpha=0.5,bins=160,label=x) |
| 529 | + |
| 530 | + plt.title(f'{band} Epoch Averages') |
| 531 | + plt.legend() |
| 532 | + plt.xlabel('uV') |
| 533 | + plt.ylabel('Count') |
| 534 | + plt.grid(True) |
| 535 | + plt.show() |
| 536 | + |
| 537 | + |
| 538 | + # basic bar chart of powerbybands comparing between catergories with error bars encompassing 95% confidence interval assuming normal distrobutions |
| 539 | + def basicComparisons(self, returnAsImageArray=False): |
| 540 | + if returnAsImageArray: |
| 541 | + plt.switch_backend('Agg') |
| 542 | + |
| 543 | + fig, ax = plt.subplots() |
| 544 | + bar_width = .3 |
| 545 | + currentBarDist = bar_width |
| 546 | + figs = {x:0 for x in self.fileBundles} |
| 547 | + index = np.arange(5) |
| 548 | + for x in self.accumulatedPowerBandStats: |
| 549 | + print(x,self.accumulatedPowerBandStats[x]) |
| 550 | + ax.bar(index+currentBarDist,list(self.accumulatedPowerBandStats[x].values()), bar_width, |
| 551 | + label=x,yerr=list(self.accumulatedPowerBandErrors[x].values())) |
| 552 | + currentBarDist+=bar_width |
| 553 | + |
| 554 | + ax.set_xticks(index + bar_width / 2) |
| 555 | + ax.set_xticklabels(self.accumulatedPowerBandStats[x].keys()) |
| 556 | + ax.set_xlabel('Band') |
| 557 | + ax.set_ylabel('Average Power (uV^2)') |
| 558 | + ax.set_title('Average Power (uV^2) by Band') |
| 559 | + ax.legend() |
| 560 | + |
| 561 | + # Render the figure to an Agg backend (image buffer) |
| 562 | + canvas = FigureCanvasAgg(fig) |
| 563 | + canvas.draw() |
| 564 | + |
| 565 | + # Convert the Agg buffer to a NumPy array |
| 566 | + img_data = np.frombuffer(canvas.tostring_rgb(), dtype='uint8') |
| 567 | + img_data = img_data.reshape(fig.canvas.get_width_height()[::-1] + (3,)) |
| 568 | + |
| 569 | + return img_data |
| 570 | + else: |
| 571 | + fig, ax = plt.subplots() |
| 572 | + bar_width = .3 |
| 573 | + currentBarDist = bar_width |
| 574 | + figs = {x:0 for x in self.fileBundles} |
| 575 | + index = np.arange(5) |
| 576 | + for x in self.accumulatedPowerBandStats: |
| 577 | + print(x,self.accumulatedPowerBandStats[x]) |
| 578 | + ax.bar(index+currentBarDist,list(self.accumulatedPowerBandStats[x].values()), bar_width, |
| 579 | + label=x,yerr=list(self.accumulatedPowerBandErrors[x].values())) |
| 580 | + currentBarDist+=bar_width |
| 581 | + |
| 582 | + ax.set_xticks(index + bar_width / 2) |
| 583 | + ax.set_xticklabels(self.accumulatedPowerBandStats[x].keys()) |
| 584 | + ax.set_xlabel('Band') |
| 585 | + ax.set_ylabel('Average Power (uV^2)') |
| 586 | + ax.set_title('Average Power (uV^2) by Band') |
| 587 | + ax.legend() |
| 588 | + |
| 589 | + plt.show() |
526 | 590 |
|
527 | 591 |
|
528 | 592 | """
|
|
0 commit comments