Skip to content
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
19 changes: 19 additions & 0 deletions src/ert/gui/tools/plot/customize/customization_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from .style_chooser import STYLESET_DEFAULT, StyleChooser

if TYPE_CHECKING:
from ert.gui.tools.plot.plot_api import PlotApiKeyDefinition
from ert.gui.tools.plot.plottery import PlotConfig


Expand All @@ -27,6 +28,7 @@ def __init__(self) -> None:
self._layout = QFormLayout()
self.setLayout(self._layout)
self._widgets: dict[str, QWidget] = {}
self._row_widgets: dict[str, QWidget] = {}

def add_row(self, title: str, widget: QWidget) -> None:
self._layout.addRow(title, widget)
Expand All @@ -40,6 +42,7 @@ def add_line_edit(
) -> None:
self[attribute_name] = ClearableLineEdit(placeholder=placeholder)
self.add_row(title, self[attribute_name])
self._row_widgets[attribute_name] = self[attribute_name]

if tool_tip is not None:
self[attribute_name].setToolTip(tool_tip)
Expand All @@ -62,6 +65,7 @@ def add_check_box(
) -> None:
self[attribute_name] = QCheckBox()
self.add_row(title, self[attribute_name])
self._row_widgets[attribute_name] = self[attribute_name]

if tool_tip is not None:
self[attribute_name].setToolTip(tool_tip)
Expand Down Expand Up @@ -90,6 +94,7 @@ def add_integer_selection_box(
sb_layout.addWidget(sb)
sb_layout.addStretch()
self.add_row(title, sb_layout) # type: ignore
self._row_widgets[attribute_name] = sb

if tool_tip is not None:
sb.setToolTip(tool_tip)
Expand Down Expand Up @@ -117,6 +122,7 @@ def add_style_chooser(
style_chooser = StyleChooser(line_style_set=line_style_set)
self[attribute_name] = style_chooser
self.add_row(title, self[attribute_name])
self._row_widgets[attribute_name] = self[attribute_name]

if tool_tip is not None:
self[attribute_name].setToolTip(tool_tip)
Expand All @@ -140,6 +146,16 @@ def update_property(
def add_spacing(self, pixels: int = 10) -> None:
self._layout.addItem(QSpacerItem(1, pixels))

def set_row_visible(self, attribute_name: str, visible: bool) -> None:
widget = self._row_widgets.get(attribute_name)
if widget is None:
return

label = self._layout.labelForField(widget)
if label is not None:
label.setVisible(visible)
widget.setVisible(visible)

def add_heading(self, title: str) -> None:
self.add_spacing(10)
self._layout.addRow(title, None)
Expand All @@ -163,6 +179,9 @@ def revert_customization(self, plot_config: PlotConfig) -> None:
"the revert_customization() function!"
)

def set_key_definition(self, key_def: PlotApiKeyDefinition) -> None:
pass


class WidgetProperty:
def __get__(self, instance: Any, owner: Any) -> Any:
Expand Down
5 changes: 5 additions & 0 deletions src/ert/gui/tools/plot/customize/customize_plot_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ def switch_plot_config_history(self, key_def: PlotApiKeyDefinition) -> None:
)
self._customization_dialog.add_copyable_key(key)
self._customization_dialog.current_plot_key_changed(key)
self._customization_dialog.set_key_definition(key_def)
self._previous_key = self._plot_config_key
self._plot_config_key = key
self._revert_customization(self.get_plot_config(), emit=False)
Expand Down Expand Up @@ -320,6 +321,10 @@ def key_selected(self, list_widget_item: QListWidgetItem) -> None:
def current_plot_key_changed(self, new_key: str | None) -> None:
self.current_key = new_key

def set_key_definition(self, key_def: PlotApiKeyDefinition) -> None:
for customization_view in self:
customization_view.set_key_definition(key_def)

def log_fn(self, action: str) -> None:
logger.info(f"Customization dialog action: {action}")

Expand Down
14 changes: 14 additions & 0 deletions src/ert/gui/tools/plot/customize/default_customization_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@
from .customization_view import CustomizationView, WidgetProperty

if TYPE_CHECKING:
from ert.gui.tools.plot.plot_api import PlotApiKeyDefinition
from ert.gui.tools.plot.plottery import PlotConfig


def _supports_observations(key_def: "PlotApiKeyDefinition") -> bool:
return key_def.observations or key_def.metadata.get("data_origin") == "field"


def _label_msg(label: str) -> str:
return (
f"Set to empty to use the default {label}.\n"
Expand Down Expand Up @@ -92,3 +97,12 @@ def revert_customization(self, plot_config: "PlotConfig") -> None:
if not self.is_everest:
self.history = plot_config.is_history_enabled()
self.observations = plot_config.is_observations_enabled()

@override
def set_key_definition(self, key_def: "PlotApiKeyDefinition") -> None:
if self.is_everest:
return

is_response = key_def.response is not None
self.set_row_visible("history", is_response)
self.set_row_visible("observations", _supports_observations(key_def))
11 changes: 11 additions & 0 deletions src/ert/gui/tools/plot/customize/style_customization_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .style_chooser import STYLESET_TOGGLE, StyleChooser

if TYPE_CHECKING:
from ert.gui.tools.plot.plot_api import PlotApiKeyDefinition
from ert.gui.tools.plot.plottery import PlotConfig


Expand Down Expand Up @@ -58,7 +59,9 @@ def __init__(self) -> None:
)

self._observations_color_box = self.create_color_box("observations_color")
self["observations_color"] = self._observations_color_box
self.add_row("Observations color", self._observations_color_box)
self._row_widgets["observations_color"] = self._observations_color_box
self.update_property(
"observations_color",
StyleCustomizationView.get_observations_color,
Expand Down Expand Up @@ -107,3 +110,11 @@ def revert_customization(self, plot_config: "PlotConfig") -> None:
self.observations_style = plot_config.observations_style()
self.observations_color = plot_config.observations_color()
self.color_cycle = plot_config.line_color_cycle()

@override
def set_key_definition(self, key_def: "PlotApiKeyDefinition") -> None:
is_response = key_def.response is not None

self.set_row_visible("history_style", is_response)
self.set_row_visible("observations_style", key_def.observations)
self.set_row_visible("observations_color", key_def.observations)
5 changes: 4 additions & 1 deletion src/ert/gui/tools/plot/plottery/plots/std_dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ def plot(

im = ax_heat.imshow(data, cmap="viridis", aspect="equal")

if obs_loc is not None:
if (
obs_loc is not None
and plot_context.plotConfig().is_observations_enabled()
):
xs = obs_loc[:, 0] - 0.5
ys = obs_loc[:, 1] - 0.5

Expand Down
93 changes: 93 additions & 0 deletions tests/ert/ui_tests/gui/test_plot_customization.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import logging

import pytest

from ert.gui.tools.plot.customize.customize_plot_dialog import CustomizePlotDialog
from ert.gui.tools.plot.customize.default_customization_view import (
DefaultCustomizationView,
)
from ert.gui.tools.plot.customize.style_customization_view import StyleCustomizationView
from ert.gui.tools.plot.plot_api import PlotApiKeyDefinition


def test_that_first_tab_is_not_logged_when_opening_customize_plot_dialog(qtbot, caplog):
Expand All @@ -26,3 +30,92 @@ def test_that_first_tab_is_not_logged_when_opening_customize_plot_dialog(qtbot,
plot._tabs.setCurrentIndex(0)
assert "Customization dialog action: General" in caplog.text
assert len(caplog.records) == 2


@pytest.mark.parametrize(
(
"key_def",
"history_visible",
"observations_visible",
"observations_style_visible",
),
[
(
PlotApiKeyDefinition(
key="MY_PARAM",
index_type=None,
observations=False,
dimensionality=1,
metadata={"data_origin": "gen_kw"},
),
False,
False,
False,
),
(
PlotApiKeyDefinition(
key="MY_FIELD",
index_type=None,
observations=False,
dimensionality=3,
metadata={"data_origin": "field"},
),
False,
True,
False,
),
(
PlotApiKeyDefinition(
key="MY_SURFACE",
index_type=None,
observations=False,
dimensionality=3,
metadata={"data_origin": "surface"},
),
False,
False,
False,
),
(
PlotApiKeyDefinition(
key="WWCT:OP_1",
index_type="VALUE",
observations=True,
dimensionality=2,
metadata={"data_origin": "summary"},
response=object(), # type: ignore[arg-type]
),
True,
True,
True,
),
],
)
def test_observation_and_history_settings_visibility(
qtbot,
key_def,
history_visible,
observations_visible,
observations_style_visible,
):
general_view = DefaultCustomizationView()
style_view = StyleCustomizationView()
qtbot.addWidget(general_view)
qtbot.addWidget(style_view)

general_view.set_key_definition(key_def)
style_view.set_key_definition(key_def)

assert general_view["history"].isVisibleTo(general_view) is history_visible
assert (
general_view["observations"].isVisibleTo(general_view) is observations_visible
)
assert style_view["history_style"].isVisibleTo(style_view) is history_visible
assert (
style_view["observations_style"].isVisibleTo(style_view)
is observations_style_visible
)
assert (
style_view["observations_color"].isVisibleTo(style_view)
is observations_style_visible
)
21 changes: 21 additions & 0 deletions tests/ert/unit_tests/gui/plottery/test_stddev_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,27 @@ def test_stddev_plot_shows_boxplot(plot_context: PlotContext):
)


def test_stddev_plot_observation_locations_follow_observation_setting(
plot_context: PlotContext,
):
rng = np.random.default_rng()
figure = Figure()
std_dev_data = rng.random((5, 5))
obs_loc = np.array([[1, 2], [3, 4]])
plot_context.plotConfig.return_value.set_observations_enabled(False)

StdDevPlot().plot(
figure,
plot_context,
{},
{},
{"id": std_dev_data},
obs_loc,
)

assert len(figure.axes[0].collections) == 0


def test_that_stddev_plot_does_not_crash_and_returns_early_when_no_ensembles():
figure = Figure()
context = Mock(spec=PlotContext)
Expand Down
Loading