Best practice for plotting batch-runs


In [ ]:
%load_ext autoreload
%autoreload 2

In [ ]:
import os
from pathlib import Path
import bokeh
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from cellpy import cellreader
from cellpy.utils import ica
from cellpy.exceptions import NullData
from cellpy import log
import holoviews as hv
%matplotlib inline
hv.extension('bokeh')
log.setup_logging(default_level="INFO")

Setting file names and loading data


In [ ]:
p = Path().cwd()

In [ ]:
(p / "../../testdata/").resolve()

In [ ]:
my_data = cellreader.CellpyData()
filename = "../../testdata/hdf5/20160805_test001_45_cc.h5"
assert os.path.isfile(filename)
my_data.load(filename)
my_data.set_mass(0.1)

Creating the ica data

Method 1: using the basic dqdv-function


In [ ]:
cycle = 2
q, v = my_data.get_ccap(cycle=cycle)
dvc, dqc = ica.dqdv(v, q)
ccurve = hv.Curve((dvc, dqc))

q, v = my_data.get_dcap(cycle=cycle)
dvd, dqd = ica.dqdv(v, q)
dcurve = hv.Curve((dvd, dqd))

ccurve * dcurve

Method 2: using the dqdv_cycle function to retrive both charge and discharge dqdv


In [ ]:
cycle = 2
cycle_df = my_data.get_cap(cycle, categorical_column=True, method = "forth-and-forth")
dv, dq = ica.dqdv_cycle(cycle_df)
hv.Curve((dv, dq))

Method 3: using the dqdv_frames convinence function to retrive a pandas.DataFrame


In [ ]:
comb_ica = ica.dqdv_frames(my_data, split=False, tidy=False)
comb_ica.head()

In [ ]:
ica_charge, ica_discharge = ica.dqdv_frames(my_data, split=True, tidy=True)
ccurve = hv.Curve(ica_charge, vdims=["dq"], kdims=["voltage"])
dcurve = hv.Curve(ica_discharge, vdims=["dq"], kdims=["voltage"])
ccurve * dcurve

In [ ]:
tidy_comb_ica = ica.dqdv_frames(my_data, split=False, tidy=True)
tidy_comb_ica.head()

In [ ]:
# quick view
tidy_comb_ica.plot(x="voltage", y="dq")

In [ ]:
# tidy_comb_ica.groupby("cycle").plot(x="voltage", y="dq");
## This creates one plot pr cycle

In [ ]:
def plot_and_combine(ica_frame, selected_cycles=None, ax=None, back_end="matplotlib",
                     palette=None, xlabel="voltage", ylabel="dq", **kwargs):
    """Plot dqdv for selected cycles and combine them into a wide dataframe.
    
    This function assumes a tidy ica-frame as input.
    """
    selected_frames = []
    keys = []
    
    if back_end == "matplotlib":
        print("using matplotlib")
        if ax is None:
            fig, ax = plt.subplots()
    
    if back_end == "holoviews":
        curves = dict()
    
    if selected_cycles is not None:
        ica_frame = ica_frame.loc[ica_frame["cycle"].isin(selected_cycles)]
        
    for c, dd in ica_frame.groupby("cycle"):
        plot_label = f"cycle {c:03}"
        frame_label = f"cycle_{c:03}"
        
        if back_end == "matplotlib":
            ax.plot(dd["voltage"], dd["dq"], label=plot_label)
            
        elif back_end == "holoviews":
            curve = hv.Curve(dd[["voltage", "dq"]], vdims=["dq"])
            if palette is not None:
                curve = curve.opts(color=palette)
            curves[plot_label] = curve
        
        selected_frames.append(dd[["voltage", "dq"]])
        keys.append(frame_label)
        
    if back_end == "matplotlib":
        ax.legend()
        
    elif back_end == "holoviews":
        ax = hv.NdOverlay(curves).opts(
            xlabel=xlabel, 
            ylabel=ylabel,
            **kwargs,
        )
        
    new_df = pd.concat(selected_frames, axis=1, keys=keys)
    return ax, new_df

In [ ]:
p, new_com_ica = plot_and_combine(
    tidy_comb_ica, back_end="holoviews", width=600,
    palette=hv.Palette('Blues'),
    xlim=(0.0, 1.0),
    ylim=(-1.3e5, 2e5)
)
p

In [ ]:
selected_cycles = [1, 2, 3, 10, 15, 22]
p, new_com_ica = plot_and_combine(
    tidy_comb_ica, selected_cycles, back_end="holoviews", width=600,
    palette=hv.Palette('Spectral'),
    xlim=(0.0, 1.0),
)

In [ ]:
p

In [ ]:
new_com_ica.head()

In [ ]:
selected_cycles = [1, 2, 3, 10, 15, 22]
ax, new_com_ica = plot_and_combine(tidy_comb_ica, selected_cycles, back_end="matplotlib")

In [ ]:
new_com_ica.head()

Saving the results


In [ ]:
# new_com_ica.to_csv("example_ica_out.csv", sep=";")

In [ ]:
# %%output fig='html' filename='ica_test_out'
# p

Creating image-plots


In [ ]:
# get data
ica_charge, ica_discharge = ica.dqdv_frames(my_data, split=True, tidy=True)
# meshgridding?
# plot image