Commit ea789f26 authored by Hueser, Christian (FWCC) - 138593's avatar Hueser, Christian (FWCC) - 138593
Browse files

Resolve "Add functionality to define custom plot styles for Matplotlib plots"

parent 9bd8e5e1
Pipeline #111379 passed with stages
in 3 minutes and 42 seconds
......@@ -116,3 +116,6 @@ output/
# Unix swap files
*.swp
# Matplotlib custom plot style files
custom_plot_styles/
......@@ -286,10 +286,12 @@ SCRIPT_NAMES: []
##### Additional Files Generated
Additional to the configuration file there are two more files created:
Additional to the configuration file, three more files are created:
1. File _preprocess.py_ is created in the root folder of the project.
2. File _example_script.py_ is created in the _scripts_ folder of the project.
3. File _style_template.mplstyle_ is created in the _custom_plot_styles_
folder of the project.
#### Command _analyze_
......@@ -348,8 +350,9 @@ hifis_surveyval
│ ├── example_preprocess.py
│ ├── example_script.py
│ ├── preprocess.py
│ └── scripts
│ └── example-01-accessing-data.py
│ ├── scripts
│ │ └── example-01-accessing-data.py
│ └── style_template.mplstyle
├── hifis_surveyval.py
├── models
│ ├── answer_option.py
......@@ -363,12 +366,28 @@ hifis_surveyval
│ └── translated.py
├── plotting
│ ├── matplotlib_plotter.py
│ ├── plot_styles
│ │ └── report_style.mplstyle
│ ├── plotter.py
│ └── supported_output_format.py
└── printing
└── printer.py
```
### Matplotlib Custom Plot Styles
Files with file ending `.mplstyle` contain styling information for _Matplotlib_
plots.
An example Matplotlib plot style template called `style_template.mplstyle` is
created with the `init`-command of the _HIFIS-Surveyval_ framework.
These files can be put in a folder called `custom_plot_styles`.
Custom plot style files that are generally used within the framework need to be
put into folder `hifis_surveyval/plotting/plot_styles/`.
Plots created with _Matplotlib_ accept a `kwargs`-argument `plot_style_name`
which chooses which plot style to use for the plot.
Styles in folder `custom_plot_styles` have precedence over styles in folder
`hifis_surveyval/plotting/plot_styles/` if they have the same name.
## Resources
Below are some handy resource links:
......
......@@ -103,6 +103,7 @@ def version() -> None:
"-c",
is_flag=True,
show_default=True,
default=False,
help="Create a default config as file. "
"Overwrites any existing configuration file.",
)
......@@ -111,6 +112,7 @@ def version() -> None:
"-s",
is_flag=True,
show_default=True,
default=False,
help="Create an example script in the given script folder. "
"Overwrites any existing example script file.",
)
......@@ -119,26 +121,63 @@ def version() -> None:
"-p",
is_flag=True,
show_default=True,
default=False,
help="Create an empty preprocessing script in the given location. "
"Overwrites any existing preprocessing script.",
)
def init(config: bool, script: bool, preprocess: bool) -> None:
@click.option(
"--template",
"-t",
"style_template",
is_flag=True,
show_default=True,
default=False,
help="Create a pre-filled Matplotlib custom plot style template, "
"if not already existing.",
)
@click.option(
"--all",
"-a",
"all_files",
is_flag=True,
show_default=True,
default=True,
help="Create all files during initialization that is necessary for an "
"analysis run.",
)
def init(config: bool, script: bool, preprocess: bool, style_template: bool,
all_files: bool) \
-> None:
"""
Create a configuration file and an example script in the default locations.
Create all files with a basic configuration needed for an analysis run.
It will overwrite any existing configuration and example file.
Create a configuration file, a preprocessing script, an example script and
a custom plot style template file in the default locations.
It will overwrite any existing configuration, preprocessing and example
script file despite the custom plot style template file.
Args:
config (bool): Indicates whether to create a configuration file.
script (bool): Indicates whether to create an example analysis
script.
preprocess (bool): Indicates whether to create an example preprocess
script.
config (bool):
Indicates whether to create a configuration file. (Default: False)
script (bool):
Indicates whether to create an example analysis script.
(Default: False)
preprocess (bool):
Indicates whether to create an example preprocess script.
(Default: False)
style_template (bool):
Indicates whether to create a pre-filled Matplotlib custom plot
style file. (Default: False)
all_files (bool):
Indicates whether to create all files during initialization that
are necessary for an analysis run. (Default: True)
"""
if not config and not script and not preprocess:
if all_files and not config and not script and not preprocess \
and not style_template:
config = True
script = True
preprocess = True
style_template = True
if config:
settings.create_default_config_file()
......@@ -146,6 +185,8 @@ def init(config: bool, script: bool, preprocess: bool) -> None:
util.create_example_script(settings)
if preprocess:
util.create_preprocessing_script(settings)
if style_template:
util.create_custom_plot_style_template()
@click.argument(
......
......@@ -19,7 +19,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""This module provides helper functions."""
import os
import shutil
from pathlib import Path
from typing import Any, List, Optional
......@@ -217,3 +217,16 @@ def create_preprocessing_script(settings: Settings) -> None:
f"{Path(__file__).parent.parent.absolute()}/files/preprocess.py",
settings.PREPROCESSING_FILENAME.resolve(),
)
def create_custom_plot_style_template() -> None:
"""Create Matplotlib custom plot style file template."""
template_name: str = 'style_template.mplstyle'
template_path: Path = Path(f"hifis_surveyval/files/{template_name}")
custom_plot_styles_path: Path = Path('custom_plot_styles')
target_path: Path = custom_plot_styles_path / Path(template_name)
if not os.path.exists(custom_plot_styles_path.absolute()):
os.makedirs(custom_plot_styles_path.absolute())
if not os.path.exists(target_path.absolute()):
shutil.copy(template_path.absolute(), target_path.absolute())
text.usetex: False
font.family: 'sans-serif'
font.sans-serif: 'Helvetica'
font.style: normal
font.variant: normal
font.weight: normal
font.stretch: normal
font.size: 10
axes.titlesize: 10
axes.labelsize: 10
xtick.labelsize: 10
ytick.labelsize: 10
legend.fontsize: 10
legend.title_fontsize: 10
hifis-surveyval
Framework to help developing analysis scripts for the HIFIS Software survey.
SPDX-FileCopyrightText: 2021 HIFIS Software <support@hifis.net>
SPDX-License-Identifier: GPL-3.0-or-later
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
......@@ -29,6 +29,7 @@ The actual plotting is done by utilizing a separate plotting library called
"""
import logging
import math
import os
from inspect import FrameInfo, getmodulename, stack
from pathlib import Path
from textwrap import wrap
......@@ -38,9 +39,8 @@ from matplotlib import colors, pyplot, rcParams
from pandas import DataFrame
from hifis_surveyval.plotting.plotter import Plotter
from hifis_surveyval.plotting.supported_output_format import (
SupportedOutputFormat,
)
from hifis_surveyval.plotting.supported_output_format import \
SupportedOutputFormat
class MatplotlibPlotter(Plotter):
......@@ -126,6 +126,40 @@ class MatplotlibPlotter(Plotter):
if figure_size and len(figure_size) == 2:
MatplotlibPlotter._set_figure_size(figure_size[0], figure_size[1])
@classmethod
def _set_custom_plot_style(cls, plot_style_name: str) -> None:
"""
Set Matplotlib custom plot style.
Args:
plot_style_name: str:
This indicates which plot style to use.
"""
plot_styles_path: Path = Path('hifis_surveyval/plotting/plot_styles')
custom_plot_styles_path: Path = Path('custom_plot_styles')
file_ending: str = '.mplstyle'
if len(plot_style_name) > 0:
custom_style_file_path: Path = \
custom_plot_styles_path / Path(plot_style_name + file_ending)
style_file_path: Path = \
plot_styles_path / Path(plot_style_name + file_ending)
if os.path.exists(custom_style_file_path.absolute()):
logging.info(f"Pre-defined plot style used: "
f"{plot_style_name}.")
pyplot.style.use(custom_style_file_path.absolute())
elif os.path.exists(style_file_path.absolute()):
logging.info(f"Custom plot style used: {plot_style_name}.")
pyplot.style.use(style_file_path.absolute())
else:
logging.warning(f"Specified plot style file does not exist: "
f"{plot_style_name}")
else:
default_plot_style_name = "default"
logging.info(f"No custom plot style has been chosen, "
f"using plot style: {default_plot_style_name}")
pyplot.style.use(default_plot_style_name)
def plot_bar_chart(
self,
data_frame: DataFrame,
......@@ -173,6 +207,8 @@ class MatplotlibPlotter(Plotter):
bars being grouped side-by-side.
plot_title (str):
The title text for the plot. (Default: "")
plot_title_fontsize (float):
The font-size of the plot title. (Default: 10)
x_axis_label (str):
The label for the x-axis. Default: "")
x_label_rotation (int):
......@@ -194,7 +230,12 @@ class MatplotlibPlotter(Plotter):
This tuple indicates the aspect ratio in terms of the
figure width and height of an image to plot. (Default:
The figure is auto-sized if the figure size is not given.)
plot_style_name (str):
This indicates which plot style to use.
"""
MatplotlibPlotter._set_custom_plot_style(
kwargs.get("plot_style_name", ""))
rcParams.update({"figure.autolayout": True})
# Color map Generation:
......@@ -229,7 +270,8 @@ class MatplotlibPlotter(Plotter):
axes = pyplot.gca()
axes.set_title(kwargs.get("plot_title", ""))
axes.set_title(kwargs.get("plot_title", ""),
fontsize=kwargs.get("plot_title_fontsize", 10))
axes.set_xlabel(kwargs.get("x_axis_label", ""))
axes.set_ylabel(kwargs.get("y_axis_label", ""))
axes.set_xticklabels(
......@@ -488,7 +530,12 @@ class MatplotlibPlotter(Plotter):
This tuple indicates the aspect ratio in terms of the
figure width and height of an image to plot. (Default:
The figure is auto-sized if the figure size is not given.)
plot_style_name (str):
This indicates which plot style to use.
"""
MatplotlibPlotter._set_custom_plot_style(
kwargs.get("plot_style_name", ""))
rcParams.update({"figure.autolayout": True})
x_rotation: int = kwargs.get("x_label_rotation", 0)
......@@ -596,7 +643,12 @@ class MatplotlibPlotter(Plotter):
This tuple indicates the aspect ratio in terms of the
figure width and height of an image to plot. (Default:
The figure is auto-sized if the figure size is not given.)
plot_style_name (str):
This indicates which plot style to use.
"""
MatplotlibPlotter._set_custom_plot_style(
kwargs.get("plot_style_name", ""))
rcParams.update({"figure.autolayout": True})
color_map_name = "Blues_r" if invert_colors else "Blues"
color_map = pyplot.get_cmap(color_map_name)
......
text.usetex: True
font.family: "sans-serif"
font.sans-serif: "Helvetica"
font.style: normal
font.variant: normal
font.weight: normal
font.stretch: normal
font.size: 10
axes.titlesize: 10
axes.labelsize: 10
xtick.labelsize: 10
ytick.labelsize: 10
legend.fontsize: 10
legend.title_fontsize: 10
hifis-surveyval
Framework to help developing analysis scripts for the HIFIS Software survey.
SPDX-FileCopyrightText: 2021 HIFIS Software <support@hifis.net>
SPDX-License-Identifier: GPL-3.0-or-later
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
\ No newline at end of file
......@@ -28,9 +28,8 @@ This module provides a framework for plotters.
from abc import ABC
from pathlib import Path
from hifis_surveyval.plotting.supported_output_format import (
SupportedOutputFormat,
)
from hifis_surveyval.plotting.supported_output_format import \
SupportedOutputFormat
class Plotter(ABC):
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment