sample_arcs_from_normal()
Sample mesh data along multiple circular arcs defined by normal vectors.
Creates circular arc probes for each (center, normal, polar, angle) tuple and samples the mesh data onto each arc. For temporal datasets, automatically sweeps all time points unless time_value is specified.
Parameters
arcs(Sequence[tuple[Sequence[float], Sequence[float] | None, Sequence[float] | None, float | None]]) — List of arc definitions, each as a tuple(center, normal, polar, angle)wherecenteris[x, y, z],normalis[x, y, z]orNone(defaults to[0, 0, 1]),polaris[x, y, z]orNone(defaults to[1, 0, 0]), andangleis a float in degrees orNone(defaults to 90).resolution(int | list[int], default:100) — Number of segments to divide each arc into. Can be a singleint(applied to all arcs) or a list ofints (one per arc).time_value(float | None, default:None) — Query a specific time value instead of sweeping all time points. Ignored for static datasets.tolerance(float | None, default:None) — Tolerance for the sample operation. IfNone, PyVista generates a tolerance automatically.progress_callback(callable | None, default:None) — Callback function for progress updates. Called with(current_arc, total_arcs). Should returnTrueto continue orFalseto cancel.
Returns
Returns a list of results (one per arc), where each result is a list of dictionaries (one per time step) with a "time" key and array names as keys. Each array has:
- For scalars:
"distance","value","x","y","z"(sample point coordinates) - For vectors:
"distance","x_value","y_value","z_value","tangential"(component along arc),"normal"(component perpendicular to arc),"x","y","z"(sample point coordinates)
[
# Results for arc 0
[
{"time": 0.0, "scalar_name": {...}, ...},
{"time": 0.01, "scalar_name": {...}, ...},
...
],
# Results for arc 1
[
{"time": 0.0, "scalar_name": {...}, ...},
{"time": 0.01, "scalar_name": {...}, ...},
...
],
...
]
Examples
Sweep all time steps
from pyemsi import Plotter, examples
from matplotlib import pyplot
import numpy as np
file_path = examples.ipm_motor_path()
plt = Plotter(file_path)
data = plt.sample_arcs_from_normal(
arcs=[
((0, 0, 0), (0, 0, 1), (0.080575, 0, 0), 45),
((0, 0, 0), (0, 0, 1), (0.0569751, 0.0569751, 0), 5),
],
resolution=100,
)
fig, axes = pyplot.subplots(1, len(data), figsize=(14, 6), subplot_kw={"projection": "3d"})
axes = np.atleast_1d(axes)
for idx, arc_data in enumerate(data):
time_values = [time_data["time"] for time_data in arc_data]
distances = arc_data[0]["B-Mag (T)"]["distance"]
value_grid = np.array([time_data["B-Mag (T)"]["value"] for time_data in arc_data])
time_grid, distance_grid = np.meshgrid(time_values, distances, indexing="ij")
axes[idx].plot_surface(time_grid, distance_grid, value_grid, cmap="viridis")
axes[idx].set_xlabel("Time (s)")
axes[idx].set_ylabel("Distance Along Arc (m)")
axes[idx].set_zlabel("B-Mag (T)")
axes[idx].set_title(f"Arc {idx + 1}")
fig.suptitle("B-Mag (T) Along Sampled Arcs")
fig.tight_layout()
fig.savefig("docs/static/demos/sample_arcs_from_normal.png")

Plot three time slices
from pyemsi import Plotter, examples
from matplotlib import pyplot
import numpy as np
file_path = examples.ipm_motor_path()
plt = Plotter(file_path)
data = plt.sample_arcs_from_normal(
arcs=[
((0, 0, 0), (0, 0, 1), (0.080575, 0, 0), 45),
((0, 0, 0), (0, 0, 1), (0.0569751, 0.0569751, 0), 5),
],
resolution=100,
)
fig, axes = pyplot.subplots(1, len(data), figsize=(14, 5))
axes = np.atleast_1d(axes)
for idx, arc_data in enumerate(data):
time_indices = sorted({0, len(arc_data) // 2, len(arc_data) - 1})
for time_idx in time_indices:
axes[idx].plot(
arc_data[time_idx]["B-Mag (T)"]["distance"],
arc_data[time_idx]["B-Mag (T)"]["value"],
label=f"t = {arc_data[time_idx]['time']:.3f} s",
)
axes[idx].set_xlabel("Distance Along Arc (m)")
axes[idx].set_ylabel("B-Mag (T)")
axes[idx].set_title(f"Arc {idx + 1}")
axes[idx].legend()
fig.suptitle("B-Mag (T) Along Sampled Arcs at Three Time Points")
fig.tight_layout()
fig.savefig("docs/static/demos/sample_arcs_from_normal_time_slices.png")

Plot tangential and normal B-Vec components
from pyemsi import Plotter, examples
from matplotlib import pyplot
import numpy as np
file_path = examples.ipm_motor_path()
plt = Plotter(file_path)
data = plt.sample_arcs_from_normal(
arcs=[
((0, 0, 0), (0, 0, 1), (0.080575, 0, 0), 45),
((0, 0, 0), (0, 0, 1), (0.0569751, 0.0569751, 0), 5),
],
resolution=100,
)
fig, axes = pyplot.subplots(len(data), 2, figsize=(12, 4 * len(data)))
axes = np.array(axes, dtype=object)
if axes.ndim == 1:
axes = axes[np.newaxis, :]
for idx, arc_data in enumerate(data):
time_indices = sorted({0, len(arc_data) // 2, len(arc_data) - 1})
for time_idx in time_indices:
label = f"t = {arc_data[time_idx]['time']:.3f} s"
axes[idx, 0].plot(
arc_data[time_idx]["B-Vec (T)"]["distance"],
arc_data[time_idx]["B-Vec (T)"]["tangential"],
label=label,
)
axes[idx, 1].plot(
arc_data[time_idx]["B-Vec (T)"]["distance"],
arc_data[time_idx]["B-Vec (T)"]["normal"],
label=label,
)
axes[idx, 0].set_xlabel("Distance Along Arc (m)")
axes[idx, 0].set_ylabel("Tangential B-Vec (T)")
axes[idx, 0].set_title(f"Arc {idx + 1} Tangential")
axes[idx, 0].legend()
axes[idx, 1].set_xlabel("Distance Along Arc (m)")
axes[idx, 1].set_ylabel("Normal B-Vec (T)")
axes[idx, 1].set_title(f"Arc {idx + 1} Normal")
axes[idx, 1].legend()
fig.suptitle("B-Vec (T) Components Along Sampled Arcs at Three Time Points")
fig.tight_layout()
fig.savefig("docs/static/demos/sample_arcs_from_normal_bvec_components_time_slices.png")

Notes
- Each arc is constructed in a counterclockwise direction from the polar vector as viewed from the direction of the normal vector.
- Use
Nonefornormal,polar, orangleto get PyVista defaults:[0, 0, 1],[1, 0, 0], and 90 degrees respectively. - The
progress_callbackis useful for long-running operations. ReturnFalseto cancel processing. - For vectors,
tangentialrepresents the component along the arc direction, whilenormalrepresents the magnitude perpendicular to the arc. - The
"x","y","z"keys contain the actual 3D coordinates of sample points along each arc.
See Also
sample_arc_from_normal()- Sample single arc defined by normal vectorsample_arcs()- Sample multiple arcs defined by start/end pointssample_lines()- Sample along multiple straight lines