Skip to content

Commit dd065ae

Browse files
committed
fix: Handling of zero values when using plot_fields with scale=dB
1 parent 341812e commit dd065ae

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1919
- Fixed interpolation handling for permittivity and conductivity gradients in CustomMedium.
2020
- Restored original batch-load logging by suppressing per-task “Loading simulation…” messages.
2121
- Fixed output range of `tidy3d.plugins.invdes.FilterAndProject` to be between 0 and 1.
22+
- Handling of zero values when using `sim_data.plot_field` with `scale=dB`.
2223

2324
## [2.10.0] - 2025-12-18
2425

tests/test_data/test_sim_data.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from __future__ import annotations
44

5+
import warnings
6+
57
import matplotlib.pyplot as plt
68
import numpy as np
79
import pydantic.v1 as pydantic
@@ -624,3 +626,49 @@ def test_plot_field_monitor_data_unsupported_scale():
624626
val="real",
625627
scale="invalid",
626628
)
629+
630+
631+
def test_plot_field_with_zeros_db_scale():
632+
"""Test that plotting field data with zeros using dB scale doesn't produce warnings."""
633+
sim_data = make_sim_data()
634+
635+
# Get the existing field data and modify it to include zeros
636+
field_monitor_data = sim_data["field"]
637+
ex_data = field_monitor_data.Ex
638+
639+
# Create modified data with some zeros
640+
values = ex_data.values.copy()
641+
values[np.abs(values) < np.abs(values).max() * 0.3] = 0 # Set small values to zero
642+
ex_with_zeros = ex_data.copy(data=values)
643+
644+
# Create new field data with zeros
645+
field_data_with_zeros = field_monitor_data.updated_copy(Ex=ex_with_zeros)
646+
f_sel = ex_data.f.values[0]
647+
x_sel = ex_data.x.values[0]
648+
649+
# Plot with dB scale - this should not produce divide by zero warnings
650+
with warnings.catch_warnings():
651+
warnings.filterwarnings("error", message="divide by zero")
652+
sim_data.plot_field_monitor_data(
653+
field_monitor_data=field_data_with_zeros,
654+
field_name="Ex",
655+
val="abs",
656+
scale="dB",
657+
f=f_sel,
658+
x=x_sel,
659+
)
660+
plt.close()
661+
662+
# Also test with vmin specified (zeros replaced with floor value)
663+
with warnings.catch_warnings():
664+
warnings.filterwarnings("error", message="divide by zero")
665+
sim_data.plot_field_monitor_data(
666+
field_monitor_data=field_data_with_zeros,
667+
field_name="Ex",
668+
val="abs",
669+
scale="dB",
670+
f=f_sel,
671+
x=x_sel,
672+
vmin=-50,
673+
)
674+
plt.close()

tidy3d/components/data/sim_data.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,13 @@ def plot_field_monitor_data(
545545
("E", "abs^2"): 10,
546546
("H", "abs^2"): 10,
547547
}.get((field_name[0], val), 20)
548-
field_data = db_factor * np.log10(np.abs(field_data))
548+
# Replace zeros to prevent log10(0) warnings, preserving NaN values
549+
fill_val = np.nan
550+
if vmin is not None:
551+
fill_val = 10 ** (vmin / db_factor)
552+
field_data = np.abs(field_data)
553+
field_data = field_data.where((field_data > 0) | np.isnan(field_data), fill_val)
554+
field_data = db_factor * np.log10(field_data)
549555
field_data.name += " (dB)"
550556
cmap_type = "sequential"
551557
elif scale == "lin":

0 commit comments

Comments
 (0)