Skip to content

Commit 79c4898

Browse files
authored
Merge pull request #34 from shaia/foundation/phase3-global-defaults
Foundation/phase3 global defaults
2 parents aa84a2b + d0b64f0 commit 79c4898

12 files changed

Lines changed: 786 additions & 95 deletions

File tree

cfd_viz/__init__.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@
5757
)
5858
from .common import VTKData, ensure_dirs, find_vtk_files, read_vtk_file
5959
from .convert import from_cfd_python, from_simulation_result, to_cfd_python
60+
from .defaults import (
61+
UNSET,
62+
PlotDefaults,
63+
get_defaults,
64+
load_config_file,
65+
plot_context,
66+
reset_defaults,
67+
set_defaults,
68+
)
6069
from .info import get_recommended_settings, get_system_info, print_system_info
6170
from .quick import quick_plot, quick_plot_data, quick_plot_result
6271
from .stats import (
@@ -67,6 +76,14 @@
6776

6877
__all__ = [
6978
"__version__",
79+
# Configuration
80+
"UNSET",
81+
"PlotDefaults",
82+
"get_defaults",
83+
"set_defaults",
84+
"reset_defaults",
85+
"plot_context",
86+
"load_config_file",
7087
# I/O
7188
"VTKData",
7289
"read_vtk_file",

cfd_viz/animation/export.py

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,17 @@
1111
from matplotlib import animation
1212
from matplotlib.figure import Figure
1313

14+
from cfd_viz.defaults import UNSET, get_defaults, resolve
15+
1416
from .frames import AnimationFrames, FrameData
1517
from .renderers import create_velocity_colormap
1618

1719

1820
def export_frame_to_image(
1921
frame: FrameData,
2022
output_path: Union[str, Path],
21-
figsize: Tuple[int, int] = (16, 12),
22-
dpi: int = 150,
23+
figsize: Tuple[int, int] = UNSET,
24+
dpi: int = UNSET,
2325
include_vectors: bool = True,
2426
include_streamlines: bool = True,
2527
include_pressure: bool = True,
@@ -41,6 +43,9 @@ def export_frame_to_image(
4143
include_streamlines: Whether to include streamlines subplot.
4244
include_pressure: Whether to include pressure subplot.
4345
"""
46+
figsize = resolve(figsize, "figsize")
47+
dpi = resolve(dpi, "dpi")
48+
defaults = get_defaults()
4449
fig, axes = plt.subplots(2, 2, figsize=figsize)
4550
axes = axes.flatten()
4651

@@ -55,7 +60,9 @@ def export_frame_to_image(
5560

5661
# Panel 1: Velocity magnitude contours
5762
if velocity_mag is not None:
58-
im1 = axes[0].contourf(X, Y, velocity_mag, levels=20, cmap="viridis")
63+
im1 = axes[0].contourf(
64+
X, Y, velocity_mag, levels=defaults.levels, cmap=defaults.cmap
65+
)
5966
axes[0].set_title("Velocity Magnitude")
6067
axes[0].axis("equal")
6168
plt.colorbar(im1, ax=axes[0])
@@ -77,7 +84,7 @@ def export_frame_to_image(
7784
u_sub,
7885
v_sub,
7986
np.sqrt(u_sub**2 + v_sub**2),
80-
cmap="plasma",
87+
cmap=defaults.sequential_cmap,
8188
scale_units="xy",
8289
angles="xy",
8390
)
@@ -91,27 +98,33 @@ def export_frame_to_image(
9198
try:
9299
if velocity_mag is not None:
93100
axes[2].streamplot(
94-
X, Y, u, v, color=velocity_mag, cmap="viridis", density=2
101+
X, Y, u, v, color=velocity_mag, cmap=defaults.cmap, density=2
95102
)
96103
else:
97104
axes[2].streamplot(X, Y, u, v, density=2)
98105
except ValueError:
99106
# Streamplot can fail with certain grid configurations
100107
if velocity_mag is not None:
101-
axes[2].contourf(X, Y, velocity_mag, levels=20, cmap="viridis")
108+
axes[2].contourf(
109+
X, Y, velocity_mag, levels=defaults.levels, cmap=defaults.cmap
110+
)
102111
axes[2].set_title("Flow Streamlines")
103112
axes[2].axis("equal")
104113
else:
105114
axes[2].axis("off")
106115

107116
# Panel 4: Pressure or combined view
108117
if include_pressure and p is not None:
109-
im4 = axes[3].contourf(X, Y, p, levels=20, cmap="RdBu_r")
118+
im4 = axes[3].contourf(
119+
X, Y, p, levels=defaults.levels, cmap=defaults.diverging_cmap
120+
)
110121
axes[3].set_title("Pressure Field")
111122
axes[3].axis("equal")
112123
plt.colorbar(im4, ax=axes[3])
113124
elif velocity_mag is not None and u is not None and v is not None:
114-
im4 = axes[3].contourf(X, Y, velocity_mag, levels=20, cmap="viridis", alpha=0.7)
125+
im4 = axes[3].contourf(
126+
X, Y, velocity_mag, levels=defaults.levels, cmap=defaults.cmap, alpha=0.7
127+
)
115128
axes[3].streamplot(X, Y, u, v, color="white", density=1, linewidth=0.8)
116129
axes[3].set_title("Combined: Magnitude + Streamlines")
117130
plt.colorbar(im4, ax=axes[3])
@@ -129,8 +142,8 @@ def export_animation_frames(
129142
animation_frames: AnimationFrames,
130143
output_dir: Union[str, Path],
131144
prefix: str = "frame",
132-
figsize: Tuple[int, int] = (16, 12),
133-
dpi: int = 150,
145+
figsize: Tuple[int, int] = UNSET,
146+
dpi: int = UNSET,
134147
) -> List[str]:
135148
"""Export all frames from AnimationFrames to image files.
136149
@@ -144,6 +157,8 @@ def export_animation_frames(
144157
Returns:
145158
List of exported file paths.
146159
"""
160+
figsize = resolve(figsize, "figsize")
161+
dpi = resolve(dpi, "dpi")
147162
output_dir = Path(output_dir)
148163
output_dir.mkdir(parents=True, exist_ok=True)
149164

@@ -164,7 +179,7 @@ def save_animation(
164179
output_path: Union[str, Path],
165180
writer: str = "pillow",
166181
fps: int = 5,
167-
dpi: int = 100,
182+
dpi: int = UNSET,
168183
) -> None:
169184
"""Save a matplotlib animation to file.
170185
@@ -175,6 +190,7 @@ def save_animation(
175190
fps: Frames per second.
176191
dpi: Resolution.
177192
"""
193+
dpi = resolve(dpi, "dpi")
178194
output_path = Path(output_path)
179195
output_path.parent.mkdir(parents=True, exist_ok=True)
180196

@@ -183,7 +199,7 @@ def save_animation(
183199

184200
def create_comprehensive_frame_figure(
185201
frame: FrameData,
186-
figsize: Tuple[int, int] = (18, 10),
202+
figsize: Tuple[int, int] = UNSET,
187203
) -> Figure:
188204
"""Create a comprehensive 2x3 figure for a single frame.
189205
@@ -194,6 +210,8 @@ def create_comprehensive_frame_figure(
194210
Returns:
195211
Matplotlib Figure object.
196212
"""
213+
figsize = resolve(figsize, "figsize")
214+
defaults = get_defaults()
197215
fig, axes = plt.subplots(2, 3, figsize=figsize)
198216
axes = axes.flatten()
199217

@@ -207,15 +225,19 @@ def create_comprehensive_frame_figure(
207225
velocity_cmap = create_velocity_colormap()
208226

209227
# Velocity magnitude
210-
im0 = axes[0].contourf(X, Y, velocity_mag, levels=20, cmap=velocity_cmap)
228+
im0 = axes[0].contourf(
229+
X, Y, velocity_mag, levels=defaults.levels, cmap=velocity_cmap
230+
)
211231
axes[0].set_title("Velocity Magnitude", fontweight="bold")
212232
axes[0].set_xlabel("X")
213233
axes[0].set_ylabel("Y")
214234
axes[0].set_aspect("equal")
215235
plt.colorbar(im0, ax=axes[0])
216236

217237
# Pressure
218-
im1 = axes[1].contourf(X, Y, p, levels=20, cmap="RdBu_r")
238+
im1 = axes[1].contourf(
239+
X, Y, p, levels=defaults.levels, cmap=defaults.diverging_cmap
240+
)
219241
contours = axes[1].contour(X, Y, p, levels=8, colors="black", linewidths=0.5)
220242
axes[1].clabel(contours, inline=True, fontsize=8)
221243
axes[1].set_title("Pressure Field", fontweight="bold")
@@ -225,7 +247,7 @@ def create_comprehensive_frame_figure(
225247
plt.colorbar(im1, ax=axes[1])
226248

227249
# Vorticity
228-
im2 = axes[2].contourf(X, Y, vorticity, levels=20, cmap="seismic")
250+
im2 = axes[2].contourf(X, Y, vorticity, levels=defaults.levels, cmap="seismic")
229251
axes[2].set_title("Vorticity", fontweight="bold")
230252
axes[2].set_xlabel("X")
231253
axes[2].set_ylabel("Y")
@@ -262,7 +284,9 @@ def create_comprehensive_frame_figure(
262284
axes[4].set_aspect("equal")
263285

264286
# Combined analysis
265-
axes[5].contourf(X, Y, velocity_mag, levels=20, cmap=velocity_cmap, alpha=0.8)
287+
axes[5].contourf(
288+
X, Y, velocity_mag, levels=defaults.levels, cmap=velocity_cmap, alpha=0.8
289+
)
266290
axes[5].contour(X, Y, p, levels=6, colors="white", linewidths=1.5)
267291
if np.any(vorticity != 0):
268292
vort_threshold = np.percentile(np.abs(vorticity), 85)

0 commit comments

Comments
 (0)