From 50266076b133a671bf39f79fc46279edffe8b73d Mon Sep 17 00:00:00 2001 From: Hans Kallekleiv <16436291+HansKallekleiv@users.noreply.github.com> Date: Sun, 29 May 2022 20:53:41 +0200 Subject: [PATCH] Add color tables to `MapViewer` (#1037) --- CHANGELOG.md | 6 + .../plugins/_map_viewer_fmu/callbacks.py | 5 +- .../plugins/_map_viewer_fmu/color_tables.py | 190 ++++++++++++++++++ .../plugins/_map_viewer_fmu/layout.py | 8 +- .../plugins/_map_viewer_fmu/map_viewer_fmu.py | 18 +- 5 files changed, 222 insertions(+), 5 deletions(-) create mode 100644 webviz_subsurface/plugins/_map_viewer_fmu/color_tables.py diff --git a/CHANGELOG.md b/CHANGELOG.md index dcc2e3ab6..56f360452 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#1041](https://github.com/equinor/webviz-subsurface/pull/1041) - Increased maximum number of selected vectors in `SimulationTimeSeries` plugin. - [#1035](https://github.com/equinor/webviz-subsurface/pull/1035) - Removed `pydeck` dependency. +### Added + +- [#1037](https://github.com/equinor/webviz-subsurface/pull/1037) - `MapViewerFMU` - Color tables are now customizable from the config file. + ## [0.2.13] - 2022-05-05 ### Added @@ -41,6 +45,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#988](https://github.com/equinor/webviz-subsurface/pull/988) - `ParameterAnalysis` and `PropertyStatistics` - Switched to the VectorSelector component, and other various improvements. ### Fixed + - [#996](https://github.com/equinor/webviz-subsurface/pull/996) - `VolumetricAnalysis` - Fixed issue with the `Tornadoplot` tab not shown if volumes from both dynamic and static sources were included. - [#985](https://github.com/equinor/webviz-subsurface/pull/985) - `WellLogViewer` - Updated data format to latest version. Requires no changes in input data. @@ -68,6 +73,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#980](https://github.com/equinor/webviz-subsurface/pull/980) - Deprecated plugin `SurfaceViewerFMU`. This has been replaced by the faster, and more feature-rich plugin `MapViewerFMU`. ### Fixed + - [#965](https://github.com/equinor/webviz-subsurface/pull/965) - Allow a filtered subset of surface names for multiple attributes in `StructuralUncertainty`. - [#972](https://github.com/equinor/webviz-subsurface/pull/972) - FIxed bug occuring when ensembles had different PORE/PORV naming standards in the volumetric input files. Also fixed bug occuring if only BO and/or BG was selected in the table. - [#958](https://github.com/equinor/webviz-subsurface/pull/958) - Disable unwanted calculation of `marks` in some `RangeSlider` components. diff --git a/webviz_subsurface/plugins/_map_viewer_fmu/callbacks.py b/webviz_subsurface/plugins/_map_viewer_fmu/callbacks.py index 18bab7191..901966758 100644 --- a/webviz_subsurface/plugins/_map_viewer_fmu/callbacks.py +++ b/webviz_subsurface/plugins/_map_viewer_fmu/callbacks.py @@ -35,7 +35,7 @@ ) -# pylint: disable=too-many-locals,too-many-statements +# pylint: disable=too-many-locals,too-many-statements, too-many-arguments def plugin_callbacks( get_uuid: Callable, ensemble_surface_providers: Dict[str, EnsembleSurfaceProvider], @@ -45,6 +45,7 @@ def plugin_callbacks( map_surface_names_to_fault_polygons: Dict[str, str], well_picks_provider: Optional[WellPickProvider], fault_polygon_attribute: Optional[str], + color_tables: List[Dict], ) -> None: def selections(tab: str, colorselector: bool = False) -> Dict[str, str]: uuid = get_uuid( @@ -602,7 +603,7 @@ def _update_color_component_properties( stored_color_settings = ( stored_color_settings if stored_color_settings is not None else {} ) - colormaps = DefaultSettings.COLORMAP_OPTIONS + colormaps = [color_table["name"] for color_table in color_tables] surfids: List[str] = [] color_data: List[dict] = [] diff --git a/webviz_subsurface/plugins/_map_viewer_fmu/color_tables.py b/webviz_subsurface/plugins/_map_viewer_fmu/color_tables.py new file mode 100644 index 000000000..63ecd37de --- /dev/null +++ b/webviz_subsurface/plugins/_map_viewer_fmu/color_tables.py @@ -0,0 +1,190 @@ +default_color_tables = [ + { + "name": "Physics", + "discrete": False, + "colors": [ + [0.00, 255, 0, 0], + [0.25, 255, 255, 0], + [0.50, 0, 255, 0], + [0.75, 0, 255, 255], + [1.00, 0, 0, 255], + ], + }, + { + "name": "Rainbow", + "discrete": False, + "colors": [ + [0.00, 255, 0, 0], + [0.20, 255, 255, 0], + [0.40, 0, 255, 0], + [0.60, 0, 255, 255], + [0.80, 0, 0, 255], + [1.00, 255, 0, 255], + ], + }, + { + "name": "Porosity", + "discrete": False, + "colors": [ + [0.00, 255, 246, 117], + [0.11, 255, 243, 53], + [0.18, 255, 241, 0], + [0.25, 155, 193, 0], + [0.32, 255, 155, 23], + [0.39, 255, 162, 61], + [0.46, 255, 126, 45], + [0.53, 227, 112, 24], + [0.60, 246, 96, 31], + [0.67, 229, 39, 48], + [0.74, 252, 177, 170], + [0.81, 236, 103, 146], + [0.88, 226, 44, 118], + [1.00, 126, 40, 111], + ], + }, + { + "name": "Permeability", + "discrete": False, + "colors": [ + [0.00, 119, 63, 49], + [0.148, 135, 49, 45], + [0.246, 154, 89, 24], + [0.344, 191, 88, 22], + [0.441, 190, 142, 97], + [0.539, 255, 126, 45], + [0.637, 255, 162, 61], + [0.734, 255, 155, 23], + [0.832, 255, 241, 0], + [1.00, 255, 246, 117], + ], + }, + { + "name": "Seismic", + "discrete": False, + "colors": [[0.00, 0, 0, 255], [0.50, 255, 255, 255], [1.00, 255, 2, 2]], + }, + { + "name": "Time/Depth", + "discrete": False, + "colors": [ + [0.00, 252, 174, 169], + [0.10, 226, 44, 118], + [0.168, 229, 39, 48], + [0.234, 150, 40, 34], + [0.301, 255, 126, 45], + [0.367, 255, 162, 61], + [0.434, 255, 241, 0], + [0.50, 219, 228, 163], + [0.566, 0, 143, 74], + [0.633, 0, 110, 78], + [0.699, 0, 124, 140], + [0.766, 116, 190, 230], + [0.832, 0, 143, 212], + [0.898, 0, 51, 116], + [1.00, 74, 19, 86], + ], + }, + { + "name": "Stratigraphy", + "discrete": True, + "colors": [ + [0, 255, 120, 61], + [1, 255, 193, 0], + [2, 255, 155, 76], + [3, 255, 223, 161], + [4, 226, 44, 118], + [5, 255, 243, 53], + [6, 255, 212, 179], + [7, 255, 155, 23], + [8, 255, 246, 117], + [9, 255, 241, 0], + [10, 255, 211, 178], + [11, 255, 173, 128], + [12, 248, 152, 0], + [13, 154, 89, 24], + [14, 0, 138, 185], + [15, 82, 161, 40], + [16, 219, 228, 163], + [17, 0, 119, 64], + [18, 0, 110, 172], + [19, 116, 190, 230], + [20, 0, 155, 212], + [21, 0, 117, 190], + [22, 143, 40, 112], + [23, 220, 153, 190], + [24, 226, 44, 118], + [25, 126, 40, 111], + [26, 73, 69, 43], + [27, 203, 63, 42], + [28, 255, 198, 190], + [29, 135, 49, 45], + [30, 150, 136, 120], + [31, 198, 182, 175], + [32, 166, 154, 145], + [33, 191, 88, 22], + [34, 255, 212, 179], + [35, 251, 139, 105], + [36, 154, 89, 24], + [37, 186, 222, 200], + [38, 0, 124, 140], + [39, 87, 84, 83], + ], + }, + { + "name": "Facies", + "discrete": True, + "colors": [ + [0, 255, 193, 0], + [1, 255, 246, 117], + [2, 166, 194, 42], + [3, 149, 160, 24], + [4, 9, 143, 74], + [5, 125, 98, 15], + [6, 0, 108, 154], + [7, 0, 117, 190], + [8, 28, 22, 59], + [9, 39, 142, 199], + [10, 0, 138, 185], + [11, 52, 178, 188], + [12, 235, 63, 34], + [13, 74, 19, 86], + [14, 248, 152, 0], + [15, 1, 1, 1], + [16, 128, 128, 128], + ], + }, + { + "name": "GasOilWater", + "discrete": True, + "colors": [ + [0, 255, 46, 0], + [1, 0, 184, 0], + [2, 0, 25, 255], + [3, 179, 179, 179], + ], + }, + { + "name": "GasWater", + "discrete": True, + "colors": [[0, 255, 46, 0], [1, 0, 25, 255], [2, 179, 179, 179]], + }, + { + "name": "OilWater", + "discrete": True, + "colors": [[0, 0, 184, 0], [1, 0, 25, 255], [2, 179, 179, 179]], + }, + { + "name": "Accent", + "discrete": True, + "colors": [ + [0, 127, 201, 127], + [1, 190, 174, 212], + [2, 253, 192, 134], + [4, 255, 255, 153], + [5, 56, 108, 176], + [6, 240, 2, 127], + [7, 191, 91, 23], + [8, 102, 102, 102], + ], + }, +] diff --git a/webviz_subsurface/plugins/_map_viewer_fmu/layout.py b/webviz_subsurface/plugins/_map_viewer_fmu/layout.py index fedd782d5..8007c1f76 100644 --- a/webviz_subsurface/plugins/_map_viewer_fmu/layout.py +++ b/webviz_subsurface/plugins/_map_viewer_fmu/layout.py @@ -179,6 +179,7 @@ def main_layout( get_uuid: Callable, well_names: List[str], realizations: List[int], + color_tables: List[Dict], show_fault_polygons: bool = True, ) -> html.Div: return html.Div( @@ -219,7 +220,9 @@ def main_layout( style=LayoutStyle.MAINVIEW, color="white", highlight=False, - children=MapViewLayout(tab, get_uuid), + children=MapViewLayout( + tab, get_uuid, color_tables=color_tables + ), ), ] ), @@ -244,13 +247,14 @@ def __init__(self, tab: Tabs, get_uuid: Callable) -> None: class MapViewLayout(FullScreen): """Layout for the main view containing the map""" - def __init__(self, tab: Tabs, get_uuid: Callable) -> None: + def __init__(self, tab: Tabs, get_uuid: Callable, color_tables: List[Dict]) -> None: super().__init__( children=html.Div( DeckGLMap( id={"id": get_uuid(LayoutElements.DECKGLMAP), "tab": tab}, layers=update_map_layers(1), zoom=-4, + colorTables=color_tables, ), style={"height": LayoutStyle.MAPHEIGHT}, ), diff --git a/webviz_subsurface/plugins/_map_viewer_fmu/map_viewer_fmu.py b/webviz_subsurface/plugins/_map_viewer_fmu/map_viewer_fmu.py index a9b2fb0e9..b91389a05 100644 --- a/webviz_subsurface/plugins/_map_viewer_fmu/map_viewer_fmu.py +++ b/webviz_subsurface/plugins/_map_viewer_fmu/map_viewer_fmu.py @@ -1,3 +1,4 @@ +import json from pathlib import Path from typing import Callable, Dict, List, Optional, Tuple @@ -18,6 +19,7 @@ from ._tmp_well_pick_provider import WellPickProvider from .callbacks import plugin_callbacks +from .color_tables import default_color_tables from .layout import main_layout @@ -38,6 +40,7 @@ class MapViewerFMU(WebvizPluginABC): to the relevant well pick name * **`map_surface_names_to_fault_polygons`:** Allows mapping of file surface names to the relevant fault polygon set name +* **`color_tables`:** Color tables for the map layers --- The available maps are gathered from the `share/results/maps/` folder @@ -68,9 +71,14 @@ class MapViewerFMU(WebvizPluginABC): Well picks can be exported from RMS using this script: [extract_well_picks_from_rms.py]\ (https://github.com/equinor/webviz-subsurface-testdata/tree/master/observed_data/\ drogon_well_picks/extract_well_picks_from_rms.py) + +See [this file]\ +https://raw.githubusercontent.com/emerson-eps/color-tables/main/react-app/src/component/\ +color-tables.json for color_tables format. + """ - # pylint: disable=too-many-arguments + # pylint: disable=too-many-arguments, too-many-locals def __init__( self, app: Dash, @@ -82,6 +90,7 @@ def __init__( map_surface_names_to_fault_polygons: Dict[str, str] = None, map_surface_names_to_well_pick_names: Dict[str, str] = None, rel_surface_folder: str = "share/results/maps", + color_tables: Path = None, ): super().__init__() @@ -142,6 +151,11 @@ def __init__( if map_surface_names_to_fault_polygons is not None else {} ) + self.color_tables = ( + default_color_tables + if color_tables is None + else json.loads(color_tables.read_text()) + ) self.set_callbacks() @@ -156,6 +170,7 @@ def layout(self) -> html.Div: if self.well_pick_provider is not None else [], realizations=reals, + color_tables=self.color_tables, ) def set_callbacks(self) -> None: @@ -169,6 +184,7 @@ def set_callbacks(self) -> None: fault_polygons_server=self._fault_polygons_server, map_surface_names_to_fault_polygons=self.map_surface_names_to_fault_polygons, well_picks_provider=self.well_pick_provider, + color_tables=self.color_tables, ) def add_webvizstore(self) -> List[Tuple[Callable, list]]: