Skip to content

Commit

Permalink
Merge pull request #31 from rl-institut/fixes/labels-and-colors
Browse files Browse the repository at this point in the history
Rework labels and colors
  • Loading branch information
jnnr authored Sep 16, 2021
2 parents b3b8da5 + cefc033 commit 0003922
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 81 deletions.
6 changes: 3 additions & 3 deletions oemoflex/tools/colors.csv
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ H2 GT,magenta
CH4 GT,#d62728
Nuclear ST,pink

Liion Battery,#9467bd
BAT discharge,#9467bd
BAT charge,#9467bd
Battery,#9467bd
Battery out,#9467bd
Battery in,#9467bd

El. H2 cavern,orchid
BEV,gold
Expand Down
57 changes: 18 additions & 39 deletions oemoflex/tools/labels.yaml
Original file line number Diff line number Diff line change
@@ -1,39 +1,18 @@
!!python/tuple ['-biomass-gt', '-electricity', 'flow']: Biomass GT
!!python/tuple ['-biomass-st', '-electricity', 'flow']: Biomass ST
!!python/tuple ['-ch4-gt', '-electricity', 'flow']: CH4 GT
!!python/tuple ['-electricity', '-electricity-demand', 'flow']: El. demand
!!python/tuple ['-electricity', '-electricity-curtailment', 'flow']: Curtailment
!!python/tuple ['-electricity-shortage', '-electricity', 'flow']: Shortage
!!python/tuple ['-electricity', '-electricity-liion-battery', 'flow']: BAT charge
!!python/tuple ['-electricity-liion-battery', '-electricity', 'flow']: BAT discharge
!!python/tuple ['-solar-pv', '-electricity', 'flow']: PV
!!python/tuple ['-wind-onshore', '-electricity', 'flow']: Wind on
!!python/tuple ['-electricity-transmission', '-electricity', 'flow']: Import
!!python/tuple ['-electricity', '-electricity-transmission', 'flow']: Export
!!python/tuple ['-heat', '-heat-demand', 'flow']: Heat demand
!!python/tuple ['-ch4-boiler', '-heat', 'flow']: CH4 Boiler

biomass : Biomass
ch4: CH4
hard coal: Hard coal
oil: Oil
lignite: Lignite
other: Other

BE-biomass-st: Biomass ST
BB-biomass-st: Biomass ST
BE-electricity-curtailment: El. curtailment
BB-electricity-curtailment: Curtailment
BE-electricity-demand: El demand
BB-electricity-demand: El. Demand
BE-electricity-liion-battery: Liion Battery
BB-electricity-liion-battery: Liion Battery
BE-electricity-shortage: El. shortage
BB-electricity-shortage: Shortage
BE-BB-electricity-transmission: Transmission
BE-ch4-gt: CH4
BB-ch4-gt: CH4
BE-solar-pv: PV
BB-solar-pv: PV
BE-wind-onshore: Wind on
BB-wind-onshore: Wind
biomass-gt: Biomass GT
biomass-st: Biomass ST
ch4-boiler: CH4 Boiler
ch4-bpchp: CH4 Backpressure CHP
ch4-extchp: CH4 Extraction CHP
ch4-gt: CH4 GT
electricity-curtailment: Curtailment
electricity-demand: El. demand
electricity-electrolyzer: Electrolyzer
electricity-liion_battery: Battery
electricity-pth: res. PtH
electricity-shortage: Shortage
electricity-transmission: Import/Export
h2-gt: H2 GT
heat-demand: Heat demand
hydro-ror: Hydro ROR
solar-pv: PV
wind-onshore: Wind on
84 changes: 45 additions & 39 deletions oemoflex/tools/plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@
colors_odict[i] = colors_csv.loc["Color", i]


def check_undefined_colors(labels, color_labels):
undefined_colors = list(set(labels).difference(color_labels))

if undefined_colors:
raise KeyError(f"Undefined colors {undefined_colors}.")


def map_labels(df, labels_dict=general_labels_dict):
r"""
Renames columns according to the specifications in the label_dict. The data has multilevel
Expand Down Expand Up @@ -67,7 +74,7 @@ def rename_by_string_matching(columns, labels_dict):
List with new column names.
"""

def map_tuple(tuple, dictionary):
def map_tuple(tupl, dictionary):
r"""
The corresponding value of the tuple which is supposed to be a key in the dictionary is
retrieved.
Expand All @@ -85,56 +92,47 @@ def map_tuple(tuple, dictionary):
mapped : string
String with new column name.
"""
mapped = None

for key, value in dictionary.items():

if concrete_in_generic(tuple, key):
mapped = value
mapped = [
value for key, value in dictionary.items() if any([key in y for y in tupl])
]

else:
continue

if not mapped:
raise KeyError(f"No mapping defined for {col}.")
if len(mapped) > 1:
raise ValueError("Multiple labels are matching.")
elif not mapped:
raise KeyError(f"No label matches for {tupl}.")
else:
mapped = mapped[0]

return mapped

def concrete_in_generic(concrete_tuple, generic_tuple):
def rename_duplicated(columns_tuple, columns_mapped, dictionary):
r"""
It is checked if the concrete_tuple is contained in the generic_tuple which is a key of
the labels_dict. Thus, it is checked if a multilevel column name is contained in the
labels_dict.
Parameters
---------------
concrete_tuple : tuple
Column names which need to be adapted to a concise name.
generic_tuple : tuple
Contains old and new column names. The new column names are used for the labels in the
plot.
Returns
----------
True or False : Boolean
Boolean whether concrete_tuple is contained in generic_tuple.
Appends a suffix to those columns that are not unique. This happens in
oemof because a component can appear as the first or second entry in a tuple, which
signifies the output or input of the component, respectively.
"""
for concrete, generic in zip(concrete_tuple, generic_tuple):
if generic in concrete:
continue
columns_duplicated = columns_mapped.duplicated(keep=False)

mapped_where = [
j
for tupl in columns_tuple
for j, x in enumerate(tupl)
if any([key in x for key in dictionary.keys()])
]

else:
return False
mapped_where = pd.Series(mapped_where)

return True
columns_mapped.loc[columns_duplicated & (mapped_where == 0)] += " out"

renamed_columns = list()
columns_mapped.loc[columns_duplicated & mapped_where == 1] += " in"

for col in columns:
return columns_mapped

renamed_col = map_tuple(col, labels_dict)
# Map column names
renamed_columns = pd.Series(map(lambda x: map_tuple(x, labels_dict), columns))

renamed_columns.append(renamed_col)
# If there are duplicates, append in/out
renamed_columns = rename_duplicated(columns, renamed_columns, labels_dict)

return renamed_columns

Expand Down Expand Up @@ -314,6 +312,8 @@ def plot_dispatch_plotly(
fig : plotly.graph_objs._figure.Figure
Interactive plotly dispatch plot
"""
check_undefined_colors(df.columns, colors_odict.keys())

# make sure to obey order as definded in colors_odict
generic_order = list(colors_odict)
concrete_order = generic_order.copy()
Expand Down Expand Up @@ -395,6 +395,8 @@ def stackplot(ax, df, colors_odict):
colors_odict : collections.OrderedDictionary
Ordered dictionary with labels as keys and colourcodes as values.
"""
check_undefined_colors(df.columns, colors_odict.keys())

# y is a list which gets the correct stack order from colors file
colors = []
labels = []
Expand Down Expand Up @@ -426,6 +428,8 @@ def lineplot(ax, df, colors_odict):
colors_odict : collections.OrderedDictionary
Ordered dictionary with labels as keys and colourcodes as values.
"""
check_undefined_colors(df.columns, colors_odict.keys())

for i in df.columns:
ax.plot(df.index, df[i], color=colors_odict[i], label=i)

Expand All @@ -449,6 +453,8 @@ def plot_dispatch(ax, df, df_demand, unit, colors_odict=colors_odict):
colors_odict : collections.OrderedDictionary
Ordered dictionary with labels as keys and colourcodes as values.
"""
check_undefined_colors(df.columns, colors_odict.keys())

# apply EngFormatter on axis
ax = eng_format(ax, unit=unit)

Expand Down

0 comments on commit 0003922

Please sign in to comment.