1111from matplotlib import animation
1212from matplotlib .figure import Figure
1313
14+ from cfd_viz .defaults import UNSET , get_defaults , resolve
15+
1416from .frames import AnimationFrames , FrameData
1517from .renderers import create_velocity_colormap
1618
1719
1820def 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
184200def 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