Skip to content

Commit

Permalink
Add summary histogram option
Browse files Browse the repository at this point in the history
- Make misfits signed after aplying square root
- Refactor to adapt for new data api
- Remove regex and parse_url_query
- Apply black on ertviz/views/__init__.py
- Remove text from boxplot as not in use
  • Loading branch information
xjules committed Dec 14, 2020
1 parent a3e6b2c commit 81aa449
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 79 deletions.
7 changes: 0 additions & 7 deletions ertviz/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
import re


def parse_url_query(search):
return {key: value for (key, value) in re.findall("(\w*)\=(\w*)", search)}


from .link_and_brush_controller import link_and_brush_controller
from .ensemble_selector_controller import ensemble_selector_controller
from .multi_response_controller import multi_response_controller
Expand Down
94 changes: 38 additions & 56 deletions ertviz/controllers/observation_response_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,40 @@
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate
from copy import deepcopy
from ertviz.models import ResponsePlotModel, BoxPlotModel, PlotModel, EnsembleModel
import ertviz.assets as assets


def _get_univariate_misfits_plots(misfits_df, color):
if misfits_df is None:
return []
style = deepcopy(assets.ERTSTYLE["observation-response-plot"]["misfits"])
style["line"]["color"] = color
style["marker"]["color"] = color
x_axis = misfits_df.pop("x_axis")
misfits_data = list()
for misfits in misfits_df:
plot = PlotModel(
x_axis=x_axis,
y_axis=misfits_df[misfits].pow(1 / 2.0).values,
text=misfits,
name=misfits,
**style,
)
misfits_data.append(plot)
return misfits_data
from ertviz.models import (
ResponsePlotModel,
BoxPlotModel,
EnsembleModel,
MultiHistogramPlotModel,
)


def _get_univariate_misfits_boxplots(misfits_df, color):
if misfits_df is None:
return []

x_axis = misfits_df.pop("x_axis")
misfits_data = list()
for misfits in misfits_df.T:
plot = BoxPlotModel(
x_axis=[x_axis.loc[misfits]],
y_axis=misfits_df.T[misfits].pow(1 / 2.0).values,
text=misfits,
x_axis=[int(x_axis[misfits])],
y_axis=misfits_df.T[misfits].values,
name=f"Misfits@{int(x_axis.loc[misfits])}",
color=color,
)
misfits_data.append(plot)
return misfits_data


def _get_observation_plots(observation_df, x_axis):
data = observation_df["values"]
stds = observation_df["std"]
x_axis = observation_df["x_axis"]
style = deepcopy(assets.ERTSTYLE["observation-response-plot"]["observation"])
observation_data = PlotModel(
x_axis=x_axis,
y_axis=stds.values,
text="Observations",
name="Observations",
**style,
)
return [observation_data]

def _create_misfits_plot(response, selected_realizations, color):

def _create_misfits_plot(response, yaxis_type, selected_realizations, color):

x_axis = response.axis
# realizations = _get_univariate_misfits_plots(
realizations = _get_univariate_misfits_boxplots(
response.univariate_misfits_df(selected_realizations), color=color
response.univariate_misfits_df(selected_realizations),
color=color,
)
observations = []

# for obs in response.observations:
# observations += _get_observation_plots(obs.data_df(), x_axis)

ensemble_plot = ResponsePlotModel(
realizations,
observations,
[],
dict(
xaxis={"title": "Index"},
yaxis={"title": "Unit TODO"},
Expand All @@ -89,12 +52,13 @@ def observation_response_controller(parent, app):
[Input(parent.uuid("ensemble-selection-store"), "data")],
)
def _set_response_options(selected_ensembles):
# Should either return a union of all possible responses or the other thing which I cant think of...

if not selected_ensembles:
raise PreventUpdate
ensemble_id, _ = selected_ensembles.popitem()
ensemble = parent.ensembles.get(ensemble_id, EnsembleModel(ref_url=ensemble_id))
ensemble = parent.ensembles.get(
ensemble_id,
EnsembleModel(ref_url=ensemble_id, project_id=parent.project_identifier),
)
parent.ensembles[ensemble_id] = ensemble
return [
{
Expand Down Expand Up @@ -134,11 +98,29 @@ def _update_graph(response, yaxis_type, misfits_type, selected_ensembles):
if response in [None, ""] or not selected_ensembles:
raise PreventUpdate

if misfits_type == "Summary":
data_dict = {}
colors = {}
for ensemble_id, color in selected_ensembles.items():
ensemble = parent.ensembles.get(ensemble_id, None)
summary_df = ensemble.responses[response].summary_misfits_df(
selection=None
) # What about selections?
if summary_df is not None:
data_dict[parent.ensembles[ensemble_id]._name] = summary_df
colors[parent.ensembles[ensemble_id]._name] = color["color"]
if bool(data_dict):
plot = MultiHistogramPlotModel(
data_dict,
colors=colors,
hist=True,
kde=False,
)
return plot.repr

def _generate_plot(ensemble_id, color):
ensemble = parent.ensembles.get(ensemble_id, None)
plot = _create_misfits_plot(
ensemble.responses[response], yaxis_type, None, color
)
plot = _create_misfits_plot(ensemble.responses[response], None, color)
return plot

response_plots = [
Expand Down
6 changes: 3 additions & 3 deletions ertviz/models/plot_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,22 @@ def __init__(self, **kwargs):
self.selected = True
self._x_axis = kwargs["x_axis"]
self._y_axis = kwargs["y_axis"]
self._text = kwargs["text"]
self._name = kwargs["name"]
self._color = kwargs["color"]

@property
def repr(self):
repr_dict = dict(
# x=self._x_axis,
# x=self._x_axis, this won't work :/
# need something else to get axis right if required
y=self._y_axis,
# text=self.display_name,
name=self.display_name,
boxpoints="all",
jitter=0.3,
pointpos=-1.8,
marker_color=self._color,
)

return go.Box(repr_dict)

@property
Expand Down
24 changes: 15 additions & 9 deletions ertviz/models/realization.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pandas as pd
from ertviz.data_loader import get_data
import math


class Realization:
Expand All @@ -14,16 +14,22 @@ def __init__(self, realization_schema):
)

def _extract_univariate_misfits(self, schema):
if bool(schema): # this account for not None and empty dict
misfits_ = list(schema.values())
return pd.DataFrame(misfits_[0])
return None
# this account for not None and empty dict
if not bool(schema):
return None
misfits_ = list(schema.values())
df = pd.DataFrame(misfits_[0])
df["value_sign"] = df[["value", "sign"]].apply(
lambda row: -1.0 * math.sqrt(row[0]) if row[1] else math.sqrt(row[0]),
axis=1,
)
return df

def _extract_summary_misfits(self, schema):
if bool(schema):
misfits_ = list(schema.values())[0]
return misfits_
return None
if not bool(schema):
return None
misfits_ = list(schema.values())[0]
return misfits_

@property
def summarized_misfits_value(self):
Expand Down
25 changes: 23 additions & 2 deletions ertviz/models/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,41 @@ def data(self):
def univariate_misfits_df(self, selection=None):
if selection is not None:
data = {
realization.name: realization.univariate_misfits_df["value"]
realization.name: realization.univariate_misfits_df["value_sign"]
for realization in self.realizations
if realization.name in selection
and realization.univariate_misfits_df is not None
}
else:
data = {
realization.name: realization.univariate_misfits_df["value"]
realization.name: realization.univariate_misfits_df["value_sign"]
for realization in self.realizations
if realization.univariate_misfits_df is not None
}
if bool(data):
misfits_df = pd.DataFrame(data=data)
misfits_df["x_axis"] = self.observations[0].data_df()["x_axis"]
misfits_df.index.name = self.name
return misfits_df.astype("float64")
return None

def summary_misfits_df(self, selection=None):
if bool(selection):
data = {
realization.name: [realization.summarized_misfits_value]
for realization in self.realizations
if realization.name in selection
and bool(realization.summarized_misfits_value)
}
else:
data = {
realization.name: [realization.summarized_misfits_value]
for realization in self.realizations
if bool(realization.summarized_misfits_value)
}
if bool(data):
misfits_df = pd.DataFrame(data=data)
misfits_df.index.name = self.name
return misfits_df.astype("float64")
return None

Expand Down
3 changes: 2 additions & 1 deletion ertviz/plugins/_observation_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@


class ObservationAnalyzer(WebvizPluginABC):
def __init__(self, app):
def __init__(self, app, project_identifier: str):
super().__init__()
self.project_identifier = project_identifier
self.ensembles = {}
self.parameter_models = {}
self.set_callbacks(app)
Expand Down
2 changes: 1 addition & 1 deletion ertviz/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,4 @@ def response_obs_view(parent):
],
className="ert-graph-container",
),
]
]

0 comments on commit 81aa449

Please sign in to comment.