Source code for bluemath_tk.core.plotting.base_plotting

from abc import ABC, abstractmethod
from typing import Union
import matplotlib.pyplot as plt
from matplotlib.colors import Colormap
import plotly.graph_objects as go
import cartopy.crs as ccrs


[docs] class BasePlotting(ABC): """ Abstract base class for handling default plotting functionalities across the project. """ def __init__(self): pass
[docs] @abstractmethod def plot_line(self, x, y): """ Abstract method for plotting a line. Should be implemented by subclasses. """ pass
[docs] @abstractmethod def plot_scatter(self, x, y): """ Abstract method for plotting a scatter plot. Should be implemented by subclasses. """ pass
[docs] @abstractmethod def plot_map(self, markers=None): """ Abstract method for plotting a map. Should be implemented by subclasses. """ pass
[docs] def get_list_of_colors_for_colormap( self, cmap: Union[str, Colormap], num_colors: int ) -> list: """ Get a list of colors from a colormap. Parameters ---------- cmap : str or Colormap The colormap to use. num_colors : int The number of colors to generate. Returns ------- list A list of colors generated from the colormap. """ if isinstance(cmap, str): cmap = plt.get_cmap(cmap) return [cmap(i) for i in range(0, 256, 256 // num_colors)]
[docs] class DefaultStaticPlotting(BasePlotting): """ Concrete implementation of BasePlotting with static plotting behaviors. """ # Class-level dictionary for default settings templates = { "default": { "line": { "color": "blue", "line_style": "-", }, "scatter": { "color": "red", "size": 10, "marker": "o", }, } } def __init__(self, template: str = "default") -> None: """ Initialize an instance of the DefaultStaticPlotting class. Parameters ---------- template : str The template to use for the plotting settings. Default is "default". Notes ----- - If no keyword arguments are provided, the default template is used. - If a keyword argument is provided, it will override the corresponding default setting. - Any other provided keyword arguments will be set as instance attributes. """ super().__init__() # Update instance attributes with either default template or passed-in values / template for key, value in self.templates.get(template, "default").items(): setattr(self, f"{key}_defaults", value)
[docs] def get_subplots(self, **kwargs): fig, ax = plt.subplots(**kwargs) return fig, ax
[docs] def get_subplot(self, figsize, **kwargs): fig = plt.figure(figsize=figsize) ax = fig.add_subplot(**kwargs) return fig, ax
[docs] def plot_line(self, ax, **kwargs): c = kwargs.get("c", self.line_defaults.get("color")) kwargs.pop("c", None) ls = kwargs.get("ls", self.line_defaults.get("line_style")) kwargs.pop("ls", None) ax.plot( c=c, ls=ls, **kwargs, ) self.set_grid(ax)
[docs] def plot_scatter(self, ax, **kwargs): c = kwargs.get("c", self.scatter_defaults.get("color")) kwargs.pop("c", None) s = kwargs.get("s", self.scatter_defaults.get("size")) kwargs.pop("s", None) marker = kwargs.get("marker", self.scatter_defaults.get("marker")) kwargs.pop("marker", None) ax.scatter( c=c, s=s, marker=marker, **kwargs, ) self.set_grid(ax)
[docs] def plot_pie(self, ax, **kwargs): ax.pie(**kwargs)
[docs] def plot_map(self, ax, **kwargs): ax.set_global() ax.coastlines()
[docs] def set_title(self, ax, title="Plot Title"): """ Sets the title for a given axis. """ ax.set_title(title)
[docs] def set_xlim(self, ax, xmin, xmax): """ Sets the x-axis limits for a given axis. """ ax.set_xlim(xmin, xmax)
[docs] def set_ylim(self, ax, ymin, ymax): """ Sets the y-axis limits for a given axis. """ ax.set_ylim(ymin, ymax)
[docs] def set_xlabel(self, ax, xlabel="X-axis"): """ Sets the x-axis label for a given axis. """ ax.set_xlabel(xlabel)
[docs] def set_ylabel(self, ax, ylabel="Y-axis"): """ Sets the y-axis label for a given axis. """ ax.set_ylabel(ylabel)
[docs] def set_grid(self, ax, grid=True): """ Sets the grid for a given axis. """ ax.grid(grid)
if __name__ == "__main__": static = DefaultStaticPlotting() fig, ax = static.get_subplots() static.plot_line(ax, x=[1, 2, 3], y=[4, 5, 6])
[docs] class DefaultInteractivePlotting(BasePlotting): """ Concrete implementation of BasePlotting with interactive plotting behaviors. """ def __init__(self): super().__init__()
[docs] def plot_line(self, x, y): fig = go.Figure() fig.add_trace( go.Scatter(x=x, y=y, mode="lines", line=dict(color=self.default_line_color)) ) fig.update_layout( title="Interactive Line Plot", xaxis_title="X-axis", yaxis_title="Y-axis" ) fig.show()
[docs] def plot_scatter(self, x, y): fig = go.Figure() fig.add_trace( go.Scatter( x=x, y=y, mode="markers", marker=dict(color=self.default_scatter_color) ) ) fig.update_layout( title="Interactive Scatter Plot", xaxis_title="X-axis", yaxis_title="Y-axis" ) fig.show()
[docs] def plot_map(self, markers=None): fig = go.Figure( go.Scattermapbox( lat=[marker[0] for marker in markers] if markers else [], lon=[marker[1] for marker in markers] if markers else [], mode="markers", marker=go.scattermapbox.Marker(size=10, color="red"), ) ) fig.update_layout( mapbox=dict( style="open-street-map", center=dict( lat=self.default_map_center[0], lon=self.default_map_center[1] ), zoom=self.default_map_zoom_start, ), title="Interactive Map with Plotly", ) fig.show()