Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Several CA fixes #1383

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions activity_browser/bwutils/multilca.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from collections import OrderedDict
from copy import deepcopy
from typing import Iterable, Optional, Union
from logging import getLogger

Expand Down Expand Up @@ -433,15 +434,30 @@ def _build_dict(
"""
topcontribution_dict = dict()
for fu_or_method, col in FU_M_index.items():

contribution_col = contributions[col, :]
total = contribution_col.sum()

top_contribution = ca.sort_array(
contributions[col, :], limit=limit, limit_type=limit_type
contribution_col, limit=limit, limit_type=limit_type, total=total
)

# split and calculate remaining rest sections for positive and negative part
pos_rest = (
np.sum(contribution_col[contribution_col > 0])
- np.sum(top_contribution[top_contribution[:, 0] > 0][:, 0])
)
neg_rest = (
np.sum(contribution_col[contribution_col < 0])
- np.sum(top_contribution[top_contribution[:, 0] < 0][:, 0])
)

cont_per = OrderedDict()
cont_per.update(
{
("Total", ""): contributions[col, :].sum(),
("Rest", ""): contributions[col, :].sum()
- top_contribution[:, 0].sum(),
("Total", ""): total,
("Rest (+)", ""): pos_rest,
("Rest (-)", ""): neg_rest,
}
)
for value, index in top_contribution:
Expand Down Expand Up @@ -583,7 +599,7 @@ def get_labelled_contribution_dict(
# If the cont_dict has tuples for keys, coerce df.columns into MultiIndex
if all(isinstance(k, tuple) for k in cont_dict.keys()):
df.columns = pd.MultiIndex.from_tuples(df.columns)
special_keys = [("Total", ""), ("Rest", "")]
special_keys = [("Total", ""), ("Rest (+)", ""), ("Rest (-)", "")]

# replace all 0 values with NaN and drop all rows with only NaNs
# EXCEPT for the special keys
Expand All @@ -596,6 +612,17 @@ def get_labelled_contribution_dict(
)
df = df.loc[index]

# sort on absolute mean of a row
df_bot = deepcopy(df.iloc[3:, :])

func = lambda row: np.nanmean(np.abs(row))

df_bot["_sort_me_"] = (df_bot.select_dtypes(include=np.number)).apply(func, axis=1)
df_bot.sort_values(by="_sort_me_", ascending=False, inplace=True)
del df_bot["_sort_me_"]

df = pd.concat([df.iloc[:3, :], df_bot], axis=0)

if not mask:
joined = self.join_df_with_metadata(
df, x_fields=x_fields, y_fields=y_fields, special_keys=special_keys
Expand Down
25 changes: 23 additions & 2 deletions activity_browser/ui/figures.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,17 @@ def __init__(self):
self.plot_name = "Contributions"

def plot(self, df: pd.DataFrame, unit: str = None):
"""Plot a horizontal bar chart of the process contributions."""
"""Plot a horizontal stacked bar chart of contributions,
add 'total' marker if both positive and negative results are present."""
dfp = df.copy()
dfp.index = dfp["index"]
dfp.drop(
dfp.select_dtypes(["object"]), axis=1, inplace=True
) # get rid of all non-numeric columns (metadata)
if "Total" in dfp.index:
dfp.drop("Total", inplace=True)
# drop rows if all values are 0
dfp = dfp.loc[~(dfp == 0).all(axis=1)]

self.ax.clear()
canvas_width_inches, canvas_height_inches = self.get_canvas_size_in_inches()
Expand All @@ -204,9 +207,18 @@ def plot(self, df: pd.DataFrame, unit: str = None):
dfp.index = dfp.index.str.strip("_ \n\t")
dfp.columns = dfp.columns.str.strip("_ \n\t")

# set colormap to use
items = dfp.shape[0] # how many contribution items
# skip grey and black at start/end of cmap
cmap = plt.cm.nipy_spectral_r(np.linspace(0, 1, items + 2))[1:-1]
colors = {item: color for item, color in zip(dfp.index, cmap)}
# overwrite rest values to grey
colors["Rest (+)"] = [0.8, 0.8, 0.8, 1.]
colors["Rest (-)"] = [0.8, 0.8, 0.8, 1.]

dfp.T.plot.barh(
stacked=True,
cmap=plt.cm.nipy_spectral_r,
color=colors,
ax=self.ax,
legend=False if dfp.shape[0] >= self.MAX_LEGEND else True,
)
Expand All @@ -225,6 +237,15 @@ def plot(self, df: pd.DataFrame, unit: str = None):
self.ax.grid(which="major", axis="x", color="grey", linestyle="dashed")
self.ax.set_axisbelow(True) # puts gridlines behind bars

# total marker when both negative and positive results are present
if "Rest (+)" in dfp.index and "Rest (-)" in dfp.index:
marker_size = max(min(150 / dfp.shape[1], 35), 10) # set marker size dyanmic between 10 - 35
for i, col in enumerate(dfp):
total = np.sum(dfp[col])
self.ax.plot(total, i,
markersize=marker_size, marker="d", fillstyle="left",
markerfacecolor="black", markerfacecoloralt="grey", markeredgecolor="white")

# TODO review: remove or enable

# refresh canvas
Expand Down
6 changes: 2 additions & 4 deletions activity_browser/ui/tables/models/lca_results.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ def sync(self, df):

class ContributionModel(PandasModel):
def sync(self, df):
self._dataframe = df.replace(np.nan, "", regex=True)
# drop the 'rest' row if empty
if self._dataframe.select_dtypes(include=np.number).iloc[1, :].sum() == 0:
self._dataframe.drop(labels=1, inplace=True)
# drop any rows where all numbers are 0
self._dataframe = df.loc[~(df.select_dtypes(include=np.number) == 0).all(axis=1)]
self.updated.emit()
Loading