Skip to content

Commit 619a311

Browse files
authored
Fix scalar bar display for different visualization modes (#8)
# Fix scalar bar display and add image hash validation for 3D plots Introduce `check_image_hash` utility for ensuring image consistency in 3D plot tests. Updated tests to validate rendered images using predefined hashes, added dependencies (`imagehash`, `pillow`), and refined plotting logic for structured grids. The PR makes the following changes: - Fixed scalar bar display logic to show appropriate bars based on the active scalar field - Modified structured grid plotting to handle lithology and scalar fields differently - Simplified `_plot_in_matplotlib` function by removing unused parameter - Added image hash validation to ensure visual consistency in tests - Updated all 3D plot tests to verify output against predefined image hashes
2 parents 25f5d09 + f3e6783 commit 619a311

File tree

5 files changed

+80
-39
lines changed

5 files changed

+80
-39
lines changed

gempy_viewer/API/_plot_3d_API.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ def plot_3d(
180180
)
181181

182182
if data_to_show.show_scalar[0] is True:
183+
# TODO: Make sure that when we are ere we do not change the scalar_bar
183184
plot_structured_grid(
184185
gempy_vista=gempy_vista,
185186
vtk_formated_regular_mesh=vtk_formated_regular_mesh,
@@ -190,8 +191,7 @@ def plot_3d(
190191
cmap='magma',
191192
**kwargs_plot_structured_grid
192193
)
193-
194-
if True:
194+
else: # * If it is not a scalar field, we use the structural frame bar
195195
set_scalar_bar(
196196
gempy_vista=gempy_vista,
197197
elements_names=structural_frame.elements_names,
@@ -207,15 +207,15 @@ def plot_3d(
207207
gempy_vista.p.show(screenshot=fig_path)
208208

209209
if image is True:
210-
show = _plot_in_matplotlib(gempy_vista, show)
210+
show = _plot_in_matplotlib(gempy_vista)
211211

212212
if show is True:
213213
gempy_vista.p.show()
214214

215215
return gempy_vista
216216

217217

218-
def _plot_in_matplotlib(gempy_vista, show):
218+
def _plot_in_matplotlib(gempy_vista):
219219
gempy_vista.p.show(screenshot=True)
220220
img = gempy_vista.p.last_image
221221
plt.imshow(img)

gempy_viewer/modules/plot_3d/drawer_structured_grid_3d.py

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -45,35 +45,25 @@ def plot_structured_grid(
4545
crinkle=False,
4646
invert=True
4747
)
48-
49-
add_regular_grid_mesh(
50-
gempy_vista=gempy_vista,
51-
structured_grid=structured_grid,
52-
cmap=cmap,
53-
opacity=opacity, # BUG pass this as an argument
54-
**kwargs
55-
)
56-
57-
58-
def add_regular_grid_mesh(
59-
gempy_vista: GemPyToVista,
60-
structured_grid: "pv.StructuredGrid",
61-
cmap: Union[mcolors.Colormap or str],
62-
opacity: float,
63-
**kwargs
64-
):
65-
if isinstance(cmap, mcolors.Colormap):
66-
_clim = (0, cmap.N)
48+
49+
if active_scalar_field == 'lith':
50+
gempy_vista.regular_grid_actor = gempy_vista.p.add_mesh(
51+
mesh=structured_grid,
52+
show_scalar_bar=False,
53+
interpolate_before_map=True,
54+
opacity=opacity,
55+
**kwargs
56+
)
6757
else:
68-
_clim = None
69-
gempy_vista.regular_grid_actor = gempy_vista.p.add_mesh(
70-
mesh=structured_grid,
71-
# ? scalars=main_scalar, if we prepare the structured grid do we need this arg?
72-
show_scalar_bar=False,
73-
interpolate_before_map=True,
74-
opacity=opacity,
75-
**kwargs
76-
)
58+
gempy_vista.regular_grid_actor = gempy_vista.p.add_mesh(
59+
mesh=structured_grid,
60+
cmap=cmap,
61+
show_scalar_bar=True,
62+
interpolate_before_map=True,
63+
opacity=opacity,
64+
**kwargs
65+
)
66+
7767

7868

7969
def _mask_topography(structured_grid: "pv.StructuredGrid", topography: Topography) -> "pv.StructuredGrid":

requirements/dev-requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
-r optional_requirements.txt
22

33
pytest
4+
gempy
5+
imagehash
6+
pillow
47
pydantic
58
gempy_engine>=2025.2.0dev0,<2025.3.0
69
gempy>=2025.2.0dev0,<2025.3.0

tests/test_plotting/test_plot_3d.py

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import gempy as gp
66
from gempy.core.data import GeoModel
77
from gempy_viewer.core.scalar_data_type import TopographyDataType
8+
from tests.util_tests import check_image_hash
89
from tests.conftest import _one_fault_model_generator
910

1011
np.random.seed(1234)
@@ -19,10 +20,11 @@ class TestPlot3DSolutions:
1920
def test_plot_3d_solutions_default(self, one_fault_model_topo_solution):
2021
print(one_fault_model_topo_solution.structural_frame)
2122
gpv.plot_3d(one_fault_model_topo_solution, image=True)
23+
2224

2325
def test_plot_3d_solutions(self, one_fault_model_topo_solution):
2426
print(one_fault_model_topo_solution.structural_frame)
25-
gpv.plot_3d(
27+
plot3d = gpv.plot_3d(
2628
model=one_fault_model_topo_solution,
2729
show_topography=True,
2830
show_scalar=False,
@@ -32,9 +34,14 @@ def test_plot_3d_solutions(self, one_fault_model_topo_solution):
3234
image=True
3335
)
3436

37+
check_image_hash(
38+
plot3d=plot3d,
39+
hash='07040030001'
40+
)
41+
3542
def test_plot_3d_solutions_volume_and_input(self, one_fault_model_topo_solution):
3643
print(one_fault_model_topo_solution.structural_frame)
37-
gpv.plot_3d(
44+
plot3d = gpv.plot_3d(
3845
model=one_fault_model_topo_solution,
3946
show_topography=False,
4047
show_scalar=False,
@@ -45,9 +52,15 @@ def test_plot_3d_solutions_volume_and_input(self, one_fault_model_topo_solution)
4552
kwargs_plot_structured_grid = {'opacity': 0.5}
4653
)
4754

55+
56+
check_image_hash(
57+
plot3d=plot3d,
58+
hash='07400018000'
59+
)
60+
4861
def test_plot_3d_solutions_only_volume(self, one_fault_model_topo_solution):
4962
print(one_fault_model_topo_solution.structural_frame)
50-
gpv.plot_3d(
63+
plot3d =gpv.plot_3d(
5164
model=one_fault_model_topo_solution,
5265
show_topography=False,
5366
show_scalar=False,
@@ -57,9 +70,14 @@ def test_plot_3d_solutions_only_volume(self, one_fault_model_topo_solution):
5770
image=True
5871
)
5972

73+
check_image_hash(
74+
plot3d=plot3d,
75+
hash='07c00000000'
76+
)
77+
6078
def test_plot_3d_solutions_only_input(self, one_fault_model_topo_solution):
6179
print(one_fault_model_topo_solution.structural_frame)
62-
gpv.plot_3d(
80+
plot3d =gpv.plot_3d(
6381
model=one_fault_model_topo_solution,
6482
show_topography=False,
6583
show_scalar=False,
@@ -69,32 +87,53 @@ def test_plot_3d_solutions_only_input(self, one_fault_model_topo_solution):
6987
image=True
7088
)
7189

90+
check_image_hash(
91+
plot3d=plot3d,
92+
hash='06000038040'
93+
)
94+
7295
def test_plot_3d_scalar_field(self, one_fault_model_topo_solution):
73-
gpv.plot_3d(
96+
plot3d = gpv.plot_3d(
7497
model=one_fault_model_topo_solution,
7598
active_scalar_field="sf_1",
7699
show_scalar=True,
77100
show_lith=False,
101+
show_topography=False,
78102
image=True
79103
)
80104

105+
check_image_hash(
106+
plot3d=plot3d,
107+
hash='07600210000'
108+
)
109+
81110
def test_plot_3d_solutions_topography(self, one_fault_model_topo_solution):
82-
gpv.plot_3d(
111+
plot3d =gpv.plot_3d(
83112
model=one_fault_model_topo_solution,
84113
show_topography=True,
85114
topography_scalar_type=TopographyDataType.TOPOGRAPHY,
86115
image=True
87116
)
88117

118+
check_image_hash(
119+
plot3d=plot3d,
120+
hash='06480000000'
121+
)
122+
89123
def test_plot_3d_solutions_topography_geological_map(self, one_fault_model_topo_solution):
90-
gpv.plot_3d(
124+
plot3d =gpv.plot_3d(
91125
model=one_fault_model_topo_solution,
92126
show_lith=True,
93127
show_topography=True,
94128
topography_scalar_type=TopographyDataType.GEOMAP,
95129
image=True
96130
)
97131

132+
check_image_hash(
133+
plot3d=plot3d,
134+
hash='07040030001'
135+
)
136+
98137

99138
class TestPlot2DSolutionsOctrees:
100139
@pytest.fixture(scope='class')

tests/util_tests.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from gempy_viewer import GemPyToVista
2+
3+
4+
def check_image_hash(plot3d: GemPyToVista, hash:str):
5+
import imagehash
6+
from PIL import Image
7+
img = Image.fromarray(plot3d.p.last_image)
8+
hash_ = str(imagehash.colorhash(img))
9+
assert hash_ == hash, f"Image hash is not correct: {hash_}"

0 commit comments

Comments
 (0)