Module: matplotlib_plot
Expand source code
# Copyright (C) 2023-present The Project Contributors
#
# 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.
import io
import os
from abc import abstractmethod
from dataclasses import dataclass
from matplotlib import pyplot as plt
from cl.runtime import Context
from cl.runtime import View
from cl.runtime.context.env_util import EnvUtil
from cl.runtime.plots.plot import Plot
from cl.runtime.plots.plot_style import PlotStyle
from cl.runtime.views.png_view import PngView
@dataclass(slots=True, kw_only=True)
class MatplotlibPlot(Plot):
"""Base class for plot objects created using Matplotlib package."""
@abstractmethod
def _create_figure(self) -> plt.Figure:
"""Return Matplotlib figure object for the plot."""
def _load_style(self) -> PlotStyle:
"""Load style object or create with default settings if not specified."""
style = Context.current().load_one(PlotStyle, self.style, is_key_optional=True)
if style is None:
# Use default values if not found
style = PlotStyle(plot_style_id="Default")
style.init_all()
return style
def _get_pyplot_theme(self, style: PlotStyle) -> str:
"""Get value to be set as matplotlib.pyplot theme."""
theme = "dark_background" if self.style is not None and style.dark_theme else "default"
return theme
def get_view(self) -> View:
"""Return a view object for the plot, implement using 'create_figure' method."""
# Create figure
fig = self._create_figure()
# Check if transparency required
style = self._load_style()
transparent = self.style is not None and style.dark_theme
# Save to bytes
png_buffer = io.BytesIO()
fig.savefig(png_buffer, format="png", transparent=transparent)
# Get the PNG image bytes and wrap in PngView
png_bytes = png_buffer.getvalue()
result = PngView(png_bytes=png_bytes)
return result
def save_png(self) -> None:
"""Save in png format to 'base_dir/plot_id.png', implement using 'create_figure' method."""
# Create figure
fig = self._create_figure()
# Check if transparency required
style = self._load_style()
transparent = self.style is not None and style.dark_theme
# Create directory if does not exist
base_dir = EnvUtil.get_env_dir()
if not os.path.exists(base_dir):
os.makedirs(base_dir)
# Check that plot_id is set
if self.plot_id is None or self.plot_id == "":
raise RuntimeError("Cannot save figure as png because 'plot_id' field is not set.")
# Save
file_path = os.path.join(base_dir, f"{self.plot_id}.png")
fig.savefig(file_path, transparent=transparent)
Classes
class MatplotlibPlot (*, plot_id: str = None, style: PlotStyleKey | None = None)
-
Base class for plot objects created using Matplotlib package.
Expand source code
@dataclass(slots=True, kw_only=True) class MatplotlibPlot(Plot): """Base class for plot objects created using Matplotlib package.""" @abstractmethod def _create_figure(self) -> plt.Figure: """Return Matplotlib figure object for the plot.""" def _load_style(self) -> PlotStyle: """Load style object or create with default settings if not specified.""" style = Context.current().load_one(PlotStyle, self.style, is_key_optional=True) if style is None: # Use default values if not found style = PlotStyle(plot_style_id="Default") style.init_all() return style def _get_pyplot_theme(self, style: PlotStyle) -> str: """Get value to be set as matplotlib.pyplot theme.""" theme = "dark_background" if self.style is not None and style.dark_theme else "default" return theme def get_view(self) -> View: """Return a view object for the plot, implement using 'create_figure' method.""" # Create figure fig = self._create_figure() # Check if transparency required style = self._load_style() transparent = self.style is not None and style.dark_theme # Save to bytes png_buffer = io.BytesIO() fig.savefig(png_buffer, format="png", transparent=transparent) # Get the PNG image bytes and wrap in PngView png_bytes = png_buffer.getvalue() result = PngView(png_bytes=png_bytes) return result def save_png(self) -> None: """Save in png format to 'base_dir/plot_id.png', implement using 'create_figure' method.""" # Create figure fig = self._create_figure() # Check if transparency required style = self._load_style() transparent = self.style is not None and style.dark_theme # Create directory if does not exist base_dir = EnvUtil.get_env_dir() if not os.path.exists(base_dir): os.makedirs(base_dir) # Check that plot_id is set if self.plot_id is None or self.plot_id == "": raise RuntimeError("Cannot save figure as png because 'plot_id' field is not set.") # Save file_path = os.path.join(base_dir, f"{self.plot_id}.png") fig.savefig(file_path, transparent=transparent)
Ancestors
- Plot
- PlotKey
- KeyMixin
- RecordMixin
- abc.ABC
- typing.Generic
Subclasses
Static methods
def get_key_type() -> Type
-
Inherited from:
Plot
.get_key_type
Return key type even when called from a record.
Fields
var plot_id -> str
-
Unique plot identifier.
var style -> PlotStyleKey | None
-
Color and layout options.
Methods
def get_key(self) -> PlotKey
-
Return a new key object whose fields populated from self, do not return self.
def get_view(self) -> View
-
Return a view object for the plot, implement using ‘create_figure’ method.
def init_all(self) -> None
-
Invoke ‘init’ for each class in the order from base to derived, then validate against schema.
def save_png(self) -> None
-
Save in png format to ‘base_dir/plot_id.png’, implement using ‘create_figure’ method.