Skip to content

Commit

Permalink
Auto-format code using pep8 (#289)
Browse files Browse the repository at this point in the history
Co-authored-by: GitHub Actions <actions@github.com>
  • Loading branch information
github-actions[bot] and actions-user authored Dec 2, 2024
1 parent 73f4a53 commit 1d7fe7c
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 132 deletions.
4 changes: 2 additions & 2 deletions src/acom_music_box/data_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,6 @@ def output(self):
# Even if we are printing to the terminal, we still allow output to be written to csv if an output path is provided
if (self.args.output_format == 'csv') or (self.args.output is not None and self.args.output_format == 'terminal'):
self._output_csv()

if self.args.output_format == 'netcdf':
self._output_netcdf()
self._output_netcdf()
254 changes: 127 additions & 127 deletions src/acom_music_box/plot_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,105 +7,105 @@

logger = logging.getLogger(__name__)


class PlotOutput:
"""
A class to handle plotting operations for a DataFrame, including plotting species
concentrations over time using gnuplot or matplotlib.
This class manages the plotting tool, species list, and data output formats based on
the provided arguments, ensuring valid paths and creating necessary directories.
Attributes
----------
df : pandas.DataFrame
The DataFrame to be plotted.
args : argparse.Namespace
Command-line arguments or configurations specifying plot options.
species_list : list
A list of species to plot.
Examples
--------
>>> import pandas as pd
>>> from argparse import Namespace
>>> df = pd.DataFrame({
... 'time': [0, 1, 2],
... 'CONC.A.mol m-3': [1, 2, 3],
... 'CONC.B.mol m-3': [4, 5, 6],
... 'CONC.C.mol m-3': [7, 8, 9]
... })
>>> args = Namespace(plot='CONC.A,CONC.B', plot_tool='matplotlib')
>>> plot_output = PlotOutput(df, args)
>>> plot_output.plot()
"""

def __init__(self, df, args):
"""
Initialize the PlotOutput class with a DataFrame and configuration arguments.
A class to handle plotting operations for a DataFrame, including plotting species
concentrations over time using gnuplot or matplotlib.
This class manages the plotting tool, species list, and data output formats based on
the provided arguments, ensuring valid paths and creating necessary directories.
Parameters
Attributes
----------
df : pandas.DataFrame
The DataFrame containing the data to be output.
The DataFrame to be plotted.
args : argparse.Namespace
Arguments specifying the plot configuration, such as plot tool and species list.
"""

self.df = df.copy(deep=True)
self.args = args
self.species_list = self._format_species_list(self.args.plot.split(',') if self.args.plot else None)


def _format_species_list(self, species_list):
"""
Format the species list for plotting.
This method formats the species list for plotting by adding the 'CONC.' prefix
to each species name if it is not already present.
Parameters
----------
Command-line arguments or configurations specifying plot options.
species_list : list
A list of species to plot.
Returns
-------
list
A formatted list of species for plotting.
Examples
--------
>>> import pandas as pd
>>> from argparse import Namespace
>>> df = pd.DataFrame({
... 'time': [0, 1, 2],
... 'CONC.A.mol m-3': [1, 2, 3],
... 'CONC.B.mol m-3': [4, 5, 6],
... 'CONC.C.mol m-3': [7, 8, 9]
... })
>>> args = Namespace(plot='CONC.A,CONC.B', plot_tool='matplotlib')
>>> plot_output = PlotOutput(df, args)
>>> plot_output.plot()
"""

plot_list = None
if species_list is not None:
plot_list = []
for species in species_list:
species = species.strip()
if 'CONC.' not in species:
species = f'CONC.{species}'
plot_list.append(species)

return plot_list

def _plot_with_gnuplot(self):
"""
Plot the specified species using gnuplot.
"""
# Prepare columns and data for plotting
columns = ['time'] + self.species_list
data_to_plot = self.df[columns]

data_csv = data_to_plot.to_csv(index=False)

try:
with tempfile.NamedTemporaryFile(suffix='.csv', mode='w+', delete=True) as data_file:
data_file.write(data_csv)
data_file.flush()
data_file_path = data_file.name

plot_commands = ',\n\t'.join(
f"'{data_file_path}' using 1:{i+2} with lines title '{species}'" for i,
species in enumerate(self.species_list))

gnuplot_command = f"""
def __init__(self, df, args):
"""
Initialize the PlotOutput class with a DataFrame and configuration arguments.
Parameters
----------
df : pandas.DataFrame
The DataFrame containing the data to be output.
args : argparse.Namespace
Arguments specifying the plot configuration, such as plot tool and species list.
"""

self.df = df.copy(deep=True)
self.args = args
self.species_list = self._format_species_list(self.args.plot.split(',') if self.args.plot else None)

def _format_species_list(self, species_list):
"""
Format the species list for plotting.
This method formats the species list for plotting by adding the 'CONC.' prefix
to each species name if it is not already present.
Parameters
----------
species_list : list
A list of species to plot.
Returns
-------
list
A formatted list of species for plotting.
"""

plot_list = None
if species_list is not None:
plot_list = []
for species in species_list:
species = species.strip()
if 'CONC.' not in species:
species = f'CONC.{species}'
plot_list.append(species)

return plot_list

def _plot_with_gnuplot(self):
"""
Plot the specified species using gnuplot.
"""
# Prepare columns and data for plotting
columns = ['time'] + self.species_list
data_to_plot = self.df[columns]

data_csv = data_to_plot.to_csv(index=False)

try:
with tempfile.NamedTemporaryFile(suffix='.csv', mode='w+', delete=True) as data_file:
data_file.write(data_csv)
data_file.flush()
data_file_path = data_file.name

plot_commands = ',\n\t'.join(
f"'{data_file_path}' using 1:{i+2} with lines title '{species}'" for i,
species in enumerate(self.species_list))

gnuplot_command = f"""
set datafile separator ",";
set terminal dumb size 120,25;
set xlabel 'Time';
Expand All @@ -114,53 +114,53 @@ def _plot_with_gnuplot(self):
plot {plot_commands}
"""

subprocess.run(['gnuplot', '-e', gnuplot_command], check=True)
except FileNotFoundError as e:
logging.critical("gnuplot is not installed. Skipping plotting.")
raise e
except subprocess.CalledProcessError as e:
logging.error(f"Error occurred while plotting: {e}")
raise e
subprocess.run(['gnuplot', '-e', gnuplot_command], check=True)
except FileNotFoundError as e:
logging.critical("gnuplot is not installed. Skipping plotting.")
raise e
except subprocess.CalledProcessError as e:
logging.error(f"Error occurred while plotting: {e}")
raise e

def _plot_with_matplotlib(self):
"""
Plot the specified species using matplotlib.
"""

def _plot_with_matplotlib(self):
"""
Plot the specified species using matplotlib.
"""
indexed = self.df.set_index('time')

indexed = self.df.set_index('time')
fig, ax = plt.subplots()
indexed[self.species_list].plot(ax=ax)

fig, ax = plt.subplots()
indexed[self.species_list].plot(ax=ax)
ax.set(xlabel='Time [s]', ylabel='Concentration [mol m-3]', title='Time vs Species')

ax.set(xlabel='Time [s]', ylabel='Concentration [mol m-3]', title='Time vs Species')
ax.spines[:].set_visible(False)
ax.spines['left'].set_visible(True)
ax.spines['bottom'].set_visible(True)

ax.spines[:].set_visible(False)
ax.spines['left'].set_visible(True)
ax.spines['bottom'].set_visible(True)
ax.grid(alpha=0.5)
ax.legend()

ax.grid(alpha=0.5)
ax.legend()
# Enable interactive data cursors with hover functionality
cursor = mplcursors.cursor(hover=True)

# Enable interactive data cursors with hover functionality
cursor = mplcursors.cursor(hover=True)
# Customize the annotation format
@cursor.connect("add")
def on_add(sel):
sel.annotation.set_text(f'Time: {sel.target[0]:.2f}\nConcentration: {sel.target[1]:1.2e}')

# Customize the annotation format
@cursor.connect("add")
def on_add(sel):
sel.annotation.set_text(f'Time: {sel.target[0]:.2f}\nConcentration: {sel.target[1]:1.2e}')
plt.show()

plt.show()

def plot(self):
"""
Plot the specified species using the selected plotting tool.
"""
def plot(self):
"""
Plot the specified species using the selected plotting tool.
"""

if self.species_list is None:
logger.debug("No species provided for plotting.")
return
if self.species_list is None:
logger.debug("No species provided for plotting.")
return

if self.args.plot_tool == 'gnuplot':
self._plot_with_gnuplot()
else:
self._plot_with_matplotlib()
if self.args.plot_tool == 'gnuplot':
self._plot_with_gnuplot()
else:
self._plot_with_matplotlib()
2 changes: 1 addition & 1 deletion tests/integration/test_executable_data_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,4 @@ def test_create_directory_and_timestamped_netcdf(temp_dir):

def test_run_configuration_file(temp_dir):
result = subprocess.run(['music_box', '-c', Examples.Analytical.path], capture_output=True, text=True, cwd=temp_dir)
assert result.returncode == 0
assert result.returncode == 0
5 changes: 3 additions & 2 deletions tests/unit/test_plot_output.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from acom_music_box.plot_output import PlotOutput
import unittest
import pandas as pd
import shutil
Expand All @@ -7,7 +8,6 @@

matplotlib.use('Agg') # Use a non-interactive backend

from acom_music_box.plot_output import PlotOutput

class TestPlotOutput(unittest.TestCase):

Expand Down Expand Up @@ -44,5 +44,6 @@ def test_plot_with_matplotlib(self):
plot_output = PlotOutput(self.df, args)
plot_output.plot()


if __name__ == '__main__':
unittest.main()
unittest.main()

0 comments on commit 1d7fe7c

Please sign in to comment.