From 8775a20ba549824ae0c929d1113895030d5f4719 Mon Sep 17 00:00:00 2001 From: rasmusthog Date: Sat, 15 Oct 2022 17:14:31 +0200 Subject: [PATCH 01/10] Add function to find index closest to a val in df --- nafuma/auxillary.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/nafuma/auxillary.py b/nafuma/auxillary.py index 8044914..c01940c 100644 --- a/nafuma/auxillary.py +++ b/nafuma/auxillary.py @@ -163,4 +163,25 @@ def swap_values(options: dict, key1, key2): options[k1], options[k2] = options[k2], options[k1] - return options \ No newline at end of file + return options + + + +def find_neighbours(value, df, colname, start=0, end=-1): + ''' Finds closest match to a given value in colname of df. If there is an exact match, returns index of this value. Else, it returns the nearest neighbors (upper and lower)''' + + df = df.iloc[start:end] + + exactmatch = df[df[colname] == value] + if not exactmatch.empty: + return exactmatch.index + else: + lower_df = df[df[colname] < value][colname] + upper_df = df[df[colname] > value][colname] + + lowerneighbour_ind = lower_df.idxmax() + upperneighbour_ind = upper_df.idxmin() + + print(lowerneighbour_ind, upperneighbour_ind) + + return [lowerneighbour_ind, upperneighbour_ind] \ No newline at end of file From 317805f4c31e1e0be1153292e7403efa2e801cfb Mon Sep 17 00:00:00 2001 From: rasmusthog Date: Sat, 15 Oct 2022 17:16:04 +0200 Subject: [PATCH 02/10] Add functions to read and plot EDS spectrum --- nafuma/eds/io.py | 25 +++++++++++++++++++ nafuma/eds/plot.py | 62 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/nafuma/eds/io.py b/nafuma/eds/io.py index 8d1b34f..91c8c51 100644 --- a/nafuma/eds/io.py +++ b/nafuma/eds/io.py @@ -1,6 +1,7 @@ from PIL import Image import numpy as np import cv2 +import pandas as pd def read_image(path, weight=None, colour=None, crop=None, resize=None, brightness=None): @@ -125,3 +126,27 @@ def change_colour(image, new_colour): return image + + +def read_spectrum(path): + + headers = find_start(path) + + spectrum = pd.read_csv(path, skiprows=headers, delim_whitespace=True) + + + return spectrum + + + +def find_start(path): + + with open(path, 'r') as f: + line = f.readline() + i = 0 + while not line.startswith('Energy'): + line = f.readline() + i += 1 + + return i + diff --git a/nafuma/eds/plot.py b/nafuma/eds/plot.py index 7726f75..be8ee39 100644 --- a/nafuma/eds/plot.py +++ b/nafuma/eds/plot.py @@ -71,3 +71,65 @@ def show_image(data, options={}): else: return data['image'], None, None + + +def plot_spectrum(data: dict, options={}): + + default_options = { + 'deconvolutions': None, + 'lines': None, + 'colours': None, + 'xlabel': 'Energy', 'xunit': 'keV', 'xlim': None, + 'ylabel': 'Counts', 'yunit': 'arb. u.', 'ylim': None, 'hide_y_ticklabels': True, 'hide_y_ticks': True, + } + + options = aux.update_options(options=options, default_options=default_options) + + fig, ax = btp.prepare_plot(options=options) + + + spectrum = io.read_spectrum(data['path']) + + if options['deconvolutions']: + + deconvolutions = [] + if not isinstance(options['deconvolutions'], list): + options['deconvolutions'] = [options['deconvolutions']] + + if options['colours'] and (len(options['colours']) != len(options['deconvolutions'])): + options['colours'] = None + + for deconv in options['deconvolutions']: + df = io.read_spectrum(deconv) + deconvolutions.append(df) + + + + spectrum.plot(x='Energy', y='Counts', ax=ax, color='black') + + if options['deconvolutions']: + if options['colours']: + for deconv, colour in zip(deconvolutions, options['colours']): + ax.fill_between(x=deconv['Energy'], y1=deconv['Counts'], y2=0, color=colour, alpha=0.4) + else: + for deconv in deconvolutions: + ax.fill_between(x=deconv['Energy'], y1=deconv['Counts'], y2=0, alpha=0.4) + + + if not options['xlim']: + options['xlim'] = [spectrum['Energy'].min(), spectrum['Energy'].max()] + + if not options['ylim']: + options['ylim'] = [0, 1.1*spectrum['Counts'].max()] + + if options['lines']: + for i, (line, energy) in enumerate(options['lines'].items()): + ax.axvline(x=energy, ls='--', lw=0.5, c='black') + ax.text(s=line, x=energy, y=(0.9-0.1*i)*options['ylim'][1], fontsize=8) + + + + fig, ax = btp.adjust_plot(fig=fig, ax=ax, options=options) + + + return spectrum, fig, ax \ No newline at end of file From 2265b2a69e8746f65cf50a5983e814a4fa5b9b51 Mon Sep 17 00:00:00 2001 From: rasmusthog Date: Sat, 15 Oct 2022 17:16:34 +0200 Subject: [PATCH 03/10] Update to use new version of update_options --- nafuma/electrochemistry/plot.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nafuma/electrochemistry/plot.py b/nafuma/electrochemistry/plot.py index f8ef088..ea97681 100644 --- a/nafuma/electrochemistry/plot.py +++ b/nafuma/electrochemistry/plot.py @@ -23,7 +23,6 @@ def plot_gc(data, options=None): # Update options - required_options = ['force_reload', 'x_vals', 'y_vals', 'which_cycles', 'limit', 'exclude_cycles', 'show_plot', 'summary', 'charge', 'discharge', 'colours', 'differentiate_charge_discharge', 'gradient', 'interactive', 'interactive_session_active', 'rc_params', 'format_params', 'save_gif', 'save_path', 'fps'] default_options = { 'force_reload': False, 'x_vals': 'capacity', 'y_vals': 'voltage', @@ -42,10 +41,11 @@ def plot_gc(data, options=None): 'format_params': {}, 'save_gif': False, 'save_path': 'animation.gif', - 'fps': 1 + 'fps': 1, + 'fig': None, 'ax': None } - options = aux.update_options(options=options, required_options=required_options, default_options=default_options) + options = aux.update_options(options=options, default_options=default_options) # Read data if not already loaded From f8f5e2ebb2f0bb37890258fe01b1c2821b07c82c Mon Sep 17 00:00:00 2001 From: rasmusthog Date: Sat, 15 Oct 2022 17:16:54 +0200 Subject: [PATCH 04/10] Reset index of cycles to start at 0 --- nafuma/electrochemistry/io.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nafuma/electrochemistry/io.py b/nafuma/electrochemistry/io.py index d46a1d5..9b57f38 100644 --- a/nafuma/electrochemistry/io.py +++ b/nafuma/electrochemistry/io.py @@ -357,6 +357,12 @@ def process_neware_data(df, options={}): max_capacity = dchg_df['ions'].max() dchg_df['ions'] = np.abs(dchg_df['ions'] - max_capacity) + + if not chg_df.empty: + chg_df.reset_index(inplace=True) + if not dchg_df.empty: + dchg_df.reset_index(inplace=True) + cycles.append((chg_df, dchg_df)) From ed2bb8158e2904d04a1ef182b71ea8781fb23e74 Mon Sep 17 00:00:00 2001 From: rasmusthog Date: Sun, 16 Oct 2022 19:19:37 +0200 Subject: [PATCH 05/10] Allow specification of colours for several cycles --- nafuma/electrochemistry/plot.py | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/nafuma/electrochemistry/plot.py b/nafuma/electrochemistry/plot.py index ea97681..c32c8a1 100644 --- a/nafuma/electrochemistry/plot.py +++ b/nafuma/electrochemistry/plot.py @@ -74,13 +74,12 @@ def plot_gc(data, options=None): else: fig, ax = options['fig'], options['ax'] - for i, cycle in enumerate(data['cycles']): - if i in options['which_cycles']: + for i, cycle in enumerate(options['which_cycles']): if options['charge']: - cycle[0].plot(x=options['x_vals'], y=options['y_vals'], ax=ax, c=colours[i][0]) + data['cycles'][cycle][0].plot(x=options['x_vals'], y=options['y_vals'], ax=ax, c=colours[i][0]) if options['discharge']: - cycle[1].plot(x=options['x_vals'], y=options['y_vals'], ax=ax, c=colours[i][1]) + data['cycles'][cycle][1].plot(x=options['x_vals'], y=options['y_vals'], ax=ax, c=colours[i][1]) if options['interactive_session_active']: @@ -159,11 +158,11 @@ def plot_gc(data, options=None): else: if options['charge']: yval = 'charge_' + options['x_vals'] - data['cycles'].loc[mask].plot(x='cycle', y=yval, ax=ax, color=colours[0][0], kind='scatter', marker="$\u25EF$", s=plt.rcParams['lines.markersize']) + data['cycles'].loc[mask].plot(x='cycle', y=yval, ax=ax, color=colours[0][0], kind='scatter', marker="$\u25EF$", s=plt.rcParams['lines.markersize']*10) if options['discharge']: yval = 'discharge_' + options['x_vals'] - data['cycles'].loc[mask].plot(x='cycle', y=yval, ax=ax, color=colours[0][1], kind='scatter', marker="$\u25EF$", s=plt.rcParams['lines.markersize']) + data['cycles'].loc[mask].plot(x='cycle', y=yval, ax=ax, color=colours[0][1], kind='scatter', marker="$\u25EF$", s=plt.rcParams['lines.markersize']*10) if options['limit']: @@ -611,17 +610,25 @@ def generate_colours(cycles, options): + # Generate lists of colours colours = [] + + if len(charge_colour) != len(options['which_cycles']): + + for cycle_number in range(0, len(options['which_cycles'])): + if options['gradient']: + weight_start = ((len(options['which_cycles'])) - cycle_number)/(len(options['which_cycles'])) + weight_end = cycle_number/len(options['which_cycles']) - for cycle_number in range(0, len(cycles)): - if options['gradient']: - weight_start = (len(cycles) - cycle_number)/len(cycles) - weight_end = cycle_number/len(cycles) + charge_colour = [weight_start*start_colour + weight_end*end_colour for start_colour, end_colour in zip(charge_colour_start, charge_colour_end)] + discharge_colour = [weight_start*start_colour + weight_end*end_colour for start_colour, end_colour in zip(discharge_colour_start, discharge_colour_end)] + + colours.append([charge_colour, discharge_colour]) - charge_colour = [weight_start*start_colour + weight_end*end_colour for start_colour, end_colour in zip(charge_colour_start, charge_colour_end)] - discharge_colour = [weight_start*start_colour + weight_end*end_colour for start_colour, end_colour in zip(discharge_colour_start, discharge_colour_end)] - colours.append([charge_colour, discharge_colour]) + else: + for charge, discharge in zip(charge_colour, discharge_colour): + colours.append([charge, discharge]) return colours From 97a82353a643f44ec3f50ffc8dee6a477b5ccf63 Mon Sep 17 00:00:00 2001 From: rasmusthog Date: Mon, 17 Oct 2022 19:34:23 +0200 Subject: [PATCH 06/10] Remove print-statement --- nafuma/auxillary.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/nafuma/auxillary.py b/nafuma/auxillary.py index c01940c..9d30948 100644 --- a/nafuma/auxillary.py +++ b/nafuma/auxillary.py @@ -182,6 +182,4 @@ def find_neighbours(value, df, colname, start=0, end=-1): lowerneighbour_ind = lower_df.idxmax() upperneighbour_ind = upper_df.idxmin() - print(lowerneighbour_ind, upperneighbour_ind) - return [lowerneighbour_ind, upperneighbour_ind] \ No newline at end of file From 2e9b5e5bc066093d8440e9895278d49774a55f20 Mon Sep 17 00:00:00 2001 From: rasmusthog Date: Mon, 17 Oct 2022 19:34:39 +0200 Subject: [PATCH 07/10] Add colour mixer --- nafuma/plotting.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/nafuma/plotting.py b/nafuma/plotting.py index 6d9bf09..c0105b5 100644 --- a/nafuma/plotting.py +++ b/nafuma/plotting.py @@ -485,4 +485,30 @@ def make_animation(paths, options={}): frames[0].save(os.path.join(options['save_folder'], options['save_filename']), format='GIF', append_images=frames[1:], save_all=True, duration=(1/options['fps'])*1000, loop=0) - \ No newline at end of file + + + +def mix_colours(colour1, colour2, options): + + default_options = { + 'number_of_colours': 10, + 'weights': None + } + + options = aux.update_options(options=options, default_options=default_options) + + if not options['weights']: + options['weights'] = [x/options['number_of_colours'] for x in range(options['number_of_colours'])] + + colours = [] + for weight in options['weights']: + colour = [] + + for c1, c2 in zip(colour1, colour2): + colour.append(np.round(((1-weight)*c1 + weight*c2), 5)) + + colours.append(colour) + + + return colours + \ No newline at end of file From c02b575b54f375de354b070e6bc994685381f3f9 Mon Sep 17 00:00:00 2001 From: rasmusthog Date: Mon, 17 Oct 2022 19:35:48 +0200 Subject: [PATCH 08/10] Allow looping through cycles if max is 0 --- nafuma/electrochemistry/io.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/nafuma/electrochemistry/io.py b/nafuma/electrochemistry/io.py index 9b57f38..3bc93d0 100644 --- a/nafuma/electrochemistry/io.py +++ b/nafuma/electrochemistry/io.py @@ -41,11 +41,10 @@ def read_neware(path, options={}): # Convert from .xlsx to .csv to make readtime faster if path.endswith('xlsx'): csv_details = ''.join(path[:-5]) + '_details.csv' - csv_summary = ''.join(path[:-5]) + '_summary.csv' + csv_summary = os.path.abspath(''.join(path[:-5]) + '_summary.csv') - if not os.path.isfile(csv_summary): - Xlsx2csv(path, outputencoding="utf-8").convert(csv_summary, sheetid=3) + Xlsx2csv(path, outputencoding="utf-8").convert(os.path.abspath(csv_summary), sheetid=3) if not os.path.isfile(csv_details): Xlsx2csv(path, outputencoding="utf-8").convert(csv_details, sheetid=4) @@ -432,15 +431,17 @@ def process_biologic_data(df, options=None): df = df[headers].copy() + # Complete set of new units and get the units used in the dataset, and convert values in the DataFrame from old to new. set_units(options) options['old_units'] = get_old_units(df=df, options=options) df = add_columns(df=df, options=options) - df = unit_conversion(df=df, options=options) + df = unit_conversion(df=df, options=options) + # Creates masks for charge and discharge curves if options['mode'] == 'GC': chg_mask = (df['status'] == 1) & (df['status_change'] != 1) @@ -453,8 +454,13 @@ def process_biologic_data(df, options=None): # Initiate cycles list cycles = [] + if df['cycle'].max() == 0: + no_cycles = 1 + else: + no_cycles = int(df['cycle'].max()) + # Loop through all the cycling steps, change the current and capacities in the - for i in range(int(df["cycle"].max())): + for i in range(no_cycles): sub_df = df.loc[df['cycle'] == i].copy() From 940e794a1c07335fabf3c3c4301409ec32fba261 Mon Sep 17 00:00:00 2001 From: rasmusthog Date: Mon, 17 Oct 2022 19:36:16 +0200 Subject: [PATCH 09/10] Improve handling of colour and other minor fixes --- nafuma/electrochemistry/plot.py | 118 +++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 34 deletions(-) diff --git a/nafuma/electrochemistry/plot.py b/nafuma/electrochemistry/plot.py index c32c8a1..322b782 100644 --- a/nafuma/electrochemistry/plot.py +++ b/nafuma/electrochemistry/plot.py @@ -33,6 +33,7 @@ def plot_gc(data, options=None): 'summary': False, 'charge': True, 'discharge': True, 'colours': None, + 'markers': None, 'differentiate_charge_discharge': True, 'gradient': False, 'interactive': False, @@ -42,7 +43,9 @@ def plot_gc(data, options=None): 'save_gif': False, 'save_path': 'animation.gif', 'fps': 1, - 'fig': None, 'ax': None + 'fig': None, 'ax': None, + 'edgecolor': plt.rcParams['lines.markeredgecolor'], + 'plot_every': 1, } options = aux.update_options(options=options, default_options=default_options) @@ -52,7 +55,6 @@ def plot_gc(data, options=None): if not 'cycles' in data.keys() or options['force_reload']: data['cycles'] = ec.io.read_data(data=data, options=options) - # Update list of cycles to correct indices update_cycles_list(data=data, options=options) @@ -63,7 +65,9 @@ def plot_gc(data, options=None): - colours = generate_colours(cycles=data['cycles'], options=options) + colours = generate_colours(options=options) + markers = generate_markers(options=options) + if not options['summary']: if options['show_plot']: @@ -74,6 +78,7 @@ def plot_gc(data, options=None): else: fig, ax = options['fig'], options['ax'] + for i, cycle in enumerate(options['which_cycles']): if options['charge']: data['cycles'][cycle][0].plot(x=options['x_vals'], y=options['y_vals'], ax=ax, c=colours[i][0]) @@ -133,7 +138,10 @@ def plot_gc(data, options=None): elif options['summary'] and options['show_plot']: # Prepare plot - fig, ax = btp.prepare_plot(options=options) + if not options['fig'] and not options['ax']: + fig, ax = btp.prepare_plot(options=options) + else: + fig, ax = options['fig'], options['ax'] mask = [] for i in range(data['cycles'].shape[0]): @@ -151,18 +159,18 @@ def plot_gc(data, options=None): # FIXME To begin, the default is that y-values correspond to x-values. This should probably be implemented in more logical and consistent manner in the future. if options['x_vals'] in ['coulombic_efficiency', 'energy_efficiency']: - data['cycles'].loc[mask].plot(x='cycle', y=options['x_vals'], ax=ax, color=colours[0][0], kind='scatter', marker="$\u25EF$", s=plt.rcParams['lines.markersize']) + data['cycles'].loc[mask].plot(x='cycle', y=options['x_vals'], ax=ax, color=colours[0][1], kind='scatter', s=plt.rcParams['lines.markersize']*10, marker=markers[0], edgecolor=plt.rcParams['lines.markeredgecolor']) if options['limit']: ax.axhline(y=options['limit'], ls='--', c='black') else: if options['charge']: yval = 'charge_' + options['x_vals'] - data['cycles'].loc[mask].plot(x='cycle', y=yval, ax=ax, color=colours[0][0], kind='scatter', marker="$\u25EF$", s=plt.rcParams['lines.markersize']*10) + data['cycles'].loc[mask].plot(x='cycle', y=yval, ax=ax, color=colours[0][0], kind='scatter', s=plt.rcParams['lines.markersize']*10, marker=markers[0], edgecolor=plt.rcParams['lines.markeredgecolor']) if options['discharge']: yval = 'discharge_' + options['x_vals'] - data['cycles'].loc[mask].plot(x='cycle', y=yval, ax=ax, color=colours[0][1], kind='scatter', marker="$\u25EF$", s=plt.rcParams['lines.markersize']*10) + data['cycles'].loc[mask].plot(x='cycle', y=yval, ax=ax, color=colours[0][1], kind='scatter', s=plt.rcParams['lines.markersize']*10, marker=markers[1], edgecolor=plt.rcParams['lines.markeredgecolor']) if options['limit']: @@ -233,18 +241,26 @@ def plot_cv(data, options): # Update list of cycles to correct indices update_cycles_list(data=data, options=options) - colours = generate_colours(cycles=data['cycles'], options=options) + colours = generate_colours(options=options) if options['show_plot']: # Prepare plot fig, ax = btp.prepare_plot(options=options) - for i, cycle in enumerate(data['cycles']): - if i in options['which_cycles']: - if options['charge']: - cycle[0].plot(x=options['x_vals'], y=options['y_vals'], ax=ax, c=colours[i][0]) - if options['discharge']: - cycle[1].plot(x=options['x_vals'], y=options['y_vals'], ax=ax, c=colours[i][1]) + for i, cycle in enumerate(options['which_cycles']): + if options['charge']: + data['cycles'][cycle][0].plot(x=options['x_vals'], y=options['y_vals'], ax=ax, c=colours[i][0]) + + if options['discharge']: + data['cycles'][cycle][1].plot(x=options['x_vals'], y=options['y_vals'], ax=ax, c=colours[i][1]) + + # for i, cycle in enumerate(data['cycles']): + # if i in options['which_cycles']: + # if options['charge']: + # cycle[0].plot(x=options['x_vals'], y=options['y_vals'], ax=ax, c=colours[i][0]) + + # if options['discharge']: + # cycle[1].plot(x=options['x_vals'], y=options['y_vals'], ax=ax, c=colours[i][1]) update_labels(options) @@ -260,6 +276,7 @@ def plot_cv(data, options): options['format_params']['dpi'] = 200 + for i, cycle in enumerate(data['cycles']): if i in options['which_cycles']: @@ -359,13 +376,15 @@ def update_cycles_list(data, options: dict) -> None: options['which_cycles'] = [i-1 for i in range(which_cycles[0], which_cycles[1]+1)] - for i, cycle in enumerate(options['which_cycles']): if cycle in options['exclude_cycles']: del options['which_cycles'][i] + options['which_cycles'] = options['which_cycles'][::options['plot_every']] + + def prettify_gc_plot(fig, ax, options=None): @@ -580,16 +599,27 @@ def prettify_labels(label): -def generate_colours(cycles, options): +def generate_colours(options): + + default_options = { + 'gradient_colours': None, + } + + aux.update_options(options=options, default_options=default_options) # Assign colours from the options dictionary if it is defined, otherwise use standard colours. if options['colours']: charge_colour = options['colours'][0] discharge_colour = options['colours'][1] + + if isinstance(charge_colour, tuple): + charge_colour = [charge_colour] + if isinstance(discharge_colour, tuple): + discharge_colour = [discharge_colour] else: - charge_colour = (40/255, 70/255, 75/255) # Dark Slate Gray #28464B, coolors.co - discharge_colour = (239/255, 160/255, 11/255) # Marigold #EFA00B, coolors.co + charge_colour = [(40/255, 70/255, 75/255)] # Dark Slate Gray #28464B, coolors.co + discharge_colour = [(239/255, 160/255, 11/255)] # Marigold #EFA00B, coolors.co if not options['differentiate_charge_discharge']: discharge_colour = charge_colour @@ -599,14 +629,19 @@ def generate_colours(cycles, options): # If gradient is enabled, find start and end points for each colour if options['gradient']: - add_charge = min([(1-x)*0.75 for x in charge_colour]) - add_discharge = min([(1-x)*0.75 for x in discharge_colour]) + if not options['gradient_colours']: - charge_colour_start = charge_colour - charge_colour_end = [x+add_charge for x in charge_colour] + options['gradient_colours'] = [[None, None], [None, None]] + + add_charge = min([(1-x)*0.75 for x in charge_colour]) + add_discharge = min([(1-x)*0.75 for x in discharge_colour]) + + options['gradient_colours'][0][0] = charge_colour + options['gradient_colours'][0][1] = [x+add_charge for x in charge_colour] + + options['gradient_colours'][1][0] = discharge_colour + options['gradient_colours'][1][1] = [x+add_discharge for x in discharge_colour] - discharge_colour_start = discharge_colour - discharge_colour_end = [x+add_discharge for x in discharge_colour] @@ -615,20 +650,35 @@ def generate_colours(cycles, options): colours = [] if len(charge_colour) != len(options['which_cycles']): + if options['gradient']: + options['number_of_colours'] = len(options['which_cycles']) - for cycle_number in range(0, len(options['which_cycles'])): - if options['gradient']: - weight_start = ((len(options['which_cycles'])) - cycle_number)/(len(options['which_cycles'])) - weight_end = cycle_number/len(options['which_cycles']) + charge_colours = btp.mix_colours(colour1=options['gradient_colours'][0][0], colour2=options['gradient_colours'][0][1], options=options) + discharge_colours = btp.mix_colours(colour1=options['gradient_colours'][1][0], colour2=options['gradient_colours'][1][1], options=options) - charge_colour = [weight_start*start_colour + weight_end*end_colour for start_colour, end_colour in zip(charge_colour_start, charge_colour_end)] - discharge_colour = [weight_start*start_colour + weight_end*end_colour for start_colour, end_colour in zip(discharge_colour_start, discharge_colour_end)] - - colours.append([charge_colour, discharge_colour]) + for chg, dchg in zip(charge_colours, discharge_colours): + colours.append([chg, dchg]) + + else: + for i in options['which_cycles']: + colours.append([charge_colour, discharge_colour]) else: - for charge, discharge in zip(charge_colour, discharge_colour): - colours.append([charge, discharge]) + for chg, dchg in zip(charge_colour, discharge_colour): + colours.append([chg, dchg]) + return colours + + + +def generate_markers(options): + + if not options['markers']: + markers = ['o', 'v'] + + else: + markers = [options['markers'][0], options['markers'][1]] + + return markers \ No newline at end of file From f23d14045327d1bcfaf6c19e1c868c2ce236b9ad Mon Sep 17 00:00:00 2001 From: rasmusthog Date: Tue, 18 Oct 2022 19:23:24 +0200 Subject: [PATCH 10/10] Allow passing fig and ax to plot_cv() --- nafuma/electrochemistry/plot.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/nafuma/electrochemistry/plot.py b/nafuma/electrochemistry/plot.py index 322b782..9ab421f 100644 --- a/nafuma/electrochemistry/plot.py +++ b/nafuma/electrochemistry/plot.py @@ -209,7 +209,6 @@ def plot_gc_interactive(data, options): def plot_cv(data, options): # Update options - required_options = ['force_reload', 'x_vals', 'y_vals', 'which_cycles', 'limit', 'exclude_cycles', 'show_plot', 'charge', 'discharge', 'colours', 'differentiate_charge_discharge', 'gradient', 'interactive', 'interactive_session_active', 'rc_params', 'format_params', 'save_gif', 'save_path', 'fps'] default_options = { 'force_reload': False, 'x_vals': 'voltage', 'y_vals': 'current', @@ -227,10 +226,13 @@ def plot_cv(data, options): 'format_params': {}, 'save_gif': False, 'save_path': 'animation.gif', - 'fps': 1 + 'fps': 1, + 'plot_every': 1, + 'fig': None, + 'ax': None } - options = aux.update_options(options=options, required_options=required_options, default_options=default_options) + options = aux.update_options(options=options, default_options=default_options) # Read data if not already loaded @@ -245,7 +247,10 @@ def plot_cv(data, options): if options['show_plot']: # Prepare plot - fig, ax = btp.prepare_plot(options=options) + if not options['fig'] and not options['ax']: + fig, ax = btp.prepare_plot(options=options) + else: + fig, ax = options['fig'], options['ax'] for i, cycle in enumerate(options['which_cycles']): if options['charge']: