Source code for pysolorie.plotter

# Copyright 2023 Alireza Aghamohammadi

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from pathlib import Path
from typing import Dict, List, Optional, Tuple

import matplotlib.pyplot as plt  # type: ignore

from .logger import logger_decorator
from .numerical_integration import IrradiationCalculator


[docs] class Plotter: r""" A class used to plot the optimal orientation of a solar panel. """
[docs] @logger_decorator def plot_optimal_orientation( self, irradiation_calculator: IrradiationCalculator, from_day: int, to_day: int, path: Optional[Path] = None, plot_kwargs: Optional[Dict[str, str]] = None, savefig_kwargs: Optional[Dict[str, str]] = None, ) -> None: r""" Plots the optimal orientation of a solar panel for a range of days. :param irradiation_calculator: An instance of the IrradiationCalculator class. :type irradiation_calculator: pysolorie.IrradiationCalculator :param from_day: The starting day for the range of days. :type from_day: int :param to_day: The ending day for the range of days. :type to_day: int :param path: The path where the plot will be saved (default is None, which means the plot will be shown but not saved). :type path: Path, optional :param plot_kwargs: A dictionary of keyword arguments to be passed to the plot (default is None). :type plot_kwargs: dict, optional :param savefig_kwargs: A dictionary of keyword arguments to be passed to the savefig function (default is None). :type savefig_kwargs: dict, optional """ days, betas = self._calculate_optimal_orientations( irradiation_calculator, from_day, to_day ) plot_kwargs = plot_kwargs if plot_kwargs else {} savefig_kwargs = savefig_kwargs if savefig_kwargs else {} self._plot(days, betas, path, plot_kwargs, savefig_kwargs)
[docs] @logger_decorator def plot_total_direct_irradiation( self, irradiation_calculator: IrradiationCalculator, from_day: int, to_day: int, path: Optional[Path] = None, plot_kwargs: Optional[Dict[str, str]] = None, savefig_kwargs: Optional[Dict[str, str]] = None, ) -> None: r""" Plots the total direct irradiation for a range of days. :param irradiation_calculator: An instance of the IrradiationCalculator class. :type irradiation_calculator: pysolorie.IrradiationCalculator :param from_day: The starting day for the range of days. :type from_day: int :param to_day: The ending day for the range of days. :type to_day: int :param path: The path where the plot will be saved (default is None, which means the plot will be shown but not saved). :type path: Path, optional :param plot_kwargs: A dictionary of keyword arguments to be passed to the plot (default is None). :type plot_kwargs: dict, optional :param savefig_kwargs: A dictionary of keyword arguments to be passed to the savefig function (default is None). :type savefig_kwargs: dict, optional """ days, betas = self._calculate_optimal_orientations( irradiation_calculator, from_day, to_day ) total_direct_irradiations = [ irradiation_calculator.calculate_direct_irradiation(beta, day) for day, beta in zip(days, betas) ] plot_kwargs = plot_kwargs if plot_kwargs else {} savefig_kwargs = savefig_kwargs if savefig_kwargs else {} self._plot(days, total_direct_irradiations, path, plot_kwargs, savefig_kwargs)
@logger_decorator def _calculate_optimal_orientations( self, irradiation_calculator: IrradiationCalculator, from_day: int, to_day: int ) -> Tuple[List[int], List[float]]: days = [] betas = [] for day in range(from_day, to_day): beta = irradiation_calculator.find_optimal_orientation(day) self.logger.info( # type: ignore f"On day {day}," + f"the solar panel's optimal orientation is {beta} degrees." ) days.append(day) betas.append(beta) return days, betas def _plot( self, days: List[int], betas: List[float], path: Optional[Path], plot_kwargs: Dict[str, str], savefig_kwargs: Dict[str, str], ) -> None: figsize = plot_kwargs.get("figsize", (10, 6)) _, ax = plt.subplots(figsize=figsize) ax.plot(days, betas) ax.set_xlabel(plot_kwargs.get("xlabel", "X Axis Title")) ax.set_ylabel(plot_kwargs.get("ylabel", "Y Axis Title")) ax.set_title(plot_kwargs.get("title", "Title")) ax.grid(True) if path is not None: plt.savefig(path, **savefig_kwargs) else: plt.show()