Commit bd0a89b5138be117f37f0883b0334f4e98b2cf5e
Merge branch '3592-csfootprint' into 3592-daemon
Showing
1 changed file
with
98 additions
and
7 deletions
cscripts/csfootprint.py
| ... | ... | @@ -45,6 +45,9 @@ class csfootprint(ctools.cscript): |
| 45 | 45 | # Initialise application by calling the base class constructor |
| 46 | 46 | self._init_cscript(self.__class__.__name__, ctools.__version__, argv) |
| 47 | 47 | |
| 48 | + # Initialise members | |
| 49 | + self._statistics = {} | |
| 50 | + | |
| 48 | 51 | # Return |
| 49 | 52 | return |
| 50 | 53 | |
| ... | ... | @@ -59,7 +62,8 @@ class csfootprint(ctools.cscript): |
| 59 | 62 | Pickled instance |
| 60 | 63 | """ |
| 61 | 64 | # Set pickled dictionary |
| 62 | - state = {'base' : ctools.cscript.__getstate__(self)} | |
| 65 | + state = {'base' : ctools.cscript.__getstate__(self), | |
| 66 | + 'statistics' : self._statistics} | |
| 63 | 67 | |
| 64 | 68 | # Return pickled dictionary |
| 65 | 69 | return state |
| ... | ... | @@ -75,6 +79,7 @@ class csfootprint(ctools.cscript): |
| 75 | 79 | """ |
| 76 | 80 | # Set state |
| 77 | 81 | ctools.cscript.__setstate__(self, state['base']) |
| 82 | + self._statistics = state['statistics'] | |
| 78 | 83 | |
| 79 | 84 | # Return |
| 80 | 85 | return |
| ... | ... | @@ -494,6 +499,89 @@ class csfootprint(ctools.cscript): |
| 494 | 499 | # Return |
| 495 | 500 | return |
| 496 | 501 | |
| 502 | + # Create figure | |
| 503 | + def _create_figure(self, outfile, statistics): | |
| 504 | + """ | |
| 505 | + Create figure | |
| 506 | + | |
| 507 | + Parameters | |
| 508 | + ---------- | |
| 509 | + outfile : str | |
| 510 | + Figure file name | |
| 511 | + statistics : dict | |
| 512 | + Statistics dictionary | |
| 513 | + """ | |
| 514 | + # Optionally use matplotlib to create a figure | |
| 515 | + try: | |
| 516 | + | |
| 517 | + # Import matplotlib | |
| 518 | + import matplotlib.pyplot as plt | |
| 519 | + import matplotlib.gridspec as gridspec | |
| 520 | + | |
| 521 | + # Create figure | |
| 522 | + fig = plt.figure(figsize=(15.0,7.8)) | |
| 523 | + | |
| 524 | + # Create title and subtitle | |
| 525 | + title = 'ctools carbon footprint report' | |
| 526 | + subtitle = r'Dates: %s - %s' % \ | |
| 527 | + (statistics['use_start'], statistics['use_stop']) | |
| 528 | + fig.suptitle(title, fontsize=16) | |
| 529 | + fig.text(0.5, 0.93, subtitle, fontsize=12, ha='center') | |
| 530 | + | |
| 531 | + # Set plot margins | |
| 532 | + fig.subplots_adjust(left=0.07, bottom=0.07, right=0.97, top=0.88, wspace=0.3, hspace=0.35) | |
| 533 | + | |
| 534 | + # Divide figure | |
| 535 | + gs1 = gridspec.GridSpec(3,3) | |
| 536 | + ax1 = fig.add_subplot(gs1[0,0:2]) | |
| 537 | + ax2 = fig.add_subplot(gs1[0,2]) | |
| 538 | + | |
| 539 | + # Plot daily footprint | |
| 540 | + self._plot_daily(ax1, statistics) | |
| 541 | + | |
| 542 | + #plt.show() | |
| 543 | + | |
| 544 | + # Save figure | |
| 545 | + fig.savefig(outfile, dpi=300) | |
| 546 | + | |
| 547 | + # Log file creation | |
| 548 | + self._log_value(gammalib.NORMAL, 'Graphics file', outfile) | |
| 549 | + | |
| 550 | + # Catch exceptions | |
| 551 | + except (ImportError, RuntimeError): | |
| 552 | + | |
| 553 | + # Log file creation | |
| 554 | + self._log_value(gammalib.NORMAL, 'Graphics file', 'matplotlib not available') | |
| 555 | + | |
| 556 | + # Return | |
| 557 | + return | |
| 558 | + | |
| 559 | + # Plot daily footprint | |
| 560 | + def _plot_daily(self, ax, statistics): | |
| 561 | + """ | |
| 562 | + Plot daily footprint | |
| 563 | + | |
| 564 | + Parameters | |
| 565 | + ---------- | |
| 566 | + ax : pyplot | |
| 567 | + Plotting frame | |
| 568 | + statistics : dict | |
| 569 | + Statistics dictionary | |
| 570 | + """ | |
| 571 | + # Create bar data | |
| 572 | + days = [i for i, _ in enumerate(statistics['daily'])] | |
| 573 | + data = [entry['gCO2e'] for entry in statistics['daily']] | |
| 574 | + | |
| 575 | + # Plot bar data | |
| 576 | + ax.bar(days, data, 1.0, bottom=0.0, color='red') | |
| 577 | + | |
| 578 | + # Set labels | |
| 579 | + ax.set_title('Footprint') | |
| 580 | + ax.set_xlabel('Days since %s' % statistics['use_start'][0:10]) | |
| 581 | + ax.set_ylabel(r'g CO$_2$e') | |
| 582 | + | |
| 583 | + # Return | |
| 584 | + return | |
| 497 | 585 | |
| 498 | 586 | # Public methods |
| 499 | 587 | def process(self): |
| ... | ... | @@ -507,12 +595,12 @@ class csfootprint(ctools.cscript): |
| 507 | 595 | self._log_header1(gammalib.TERSE, 'Load statistics data') |
| 508 | 596 | |
| 509 | 597 | # Load statistics |
| 510 | - statistics = self._load_statistics() | |
| 598 | + self._statistics = self._load_statistics() | |
| 511 | 599 | |
| 512 | 600 | # Log statistics |
| 513 | - self._global_statistics(statistics) | |
| 514 | - self._daily_statistics(statistics) | |
| 515 | - self._tools_statistics(statistics) | |
| 601 | + self._global_statistics(self._statistics) | |
| 602 | + self._daily_statistics(self._statistics) | |
| 603 | + self._tools_statistics(self._statistics) | |
| 516 | 604 | |
| 517 | 605 | # Return |
| 518 | 606 | return |
| ... | ... | @@ -527,8 +615,11 @@ class csfootprint(ctools.cscript): |
| 527 | 615 | # Continue only if filename is valid |
| 528 | 616 | if self['outfile'].is_valid(): |
| 529 | 617 | |
| 530 | - # Implement saving of graphics file | |
| 531 | - pass | |
| 618 | + # Get outfile | |
| 619 | + outfile = self['outfile'].filename() | |
| 620 | + | |
| 621 | + # Create figure | |
| 622 | + self._create_figure(outfile.url(), self._statistics) | |
| 532 | 623 | |
| 533 | 624 | # ... signal that no graphics file was specified |
| 534 | 625 | else: | ... | ... |