1010def delay_spectrum (uvp , blpairs , spw , pol , average_blpairs = False ,
1111 average_times = False , fold = False , plot_noise = False ,
1212 delay = True , deltasq = False , legend = False , ax = None ,
13- component = 'real' ):
13+ component = 'real' , lines = True , markers = False , error = None ,
14+ ** kwargs ):
1415 """
1516 Plot a 1D delay spectrum (or spectra) for a group of baselines.
1617
@@ -56,10 +57,25 @@ def delay_spectrum(uvp, blpairs, spw, pol, average_blpairs=False,
5657 this case, even if the existing plot has completely different axis
5758 labels etc.) If None, a new Axes object will be created. Default: None.
5859
59- component : str
60+ component : str, optional
6061 Component of complex spectra to plot, options=['abs', 'real', 'imag'].
6162 Default: 'real'.
6263
64+ lines : bool, optional
65+ If True, plot lines between bandpowers for a given pspectrum.
66+ Default: True.
67+
68+ markers : bool, optional
69+ If True, plot circles at bandpowers. Filled for positive, empty
70+ for negative. Default: False.
71+
72+ error : str, optional
73+ If not None and if error exists in uvp stats_array, plot errors
74+ on bandpowers. Default: None.
75+
76+ kwargs : dict, optional
77+ Extra kwargs to pass to _all_ ax.plot calls.
78+
6379 Returns
6480 -------
6581 fig : matplotlib.pyplot.Figure
@@ -112,20 +128,61 @@ def delay_spectrum(uvp, blpairs, spw, pol, average_blpairs=False,
112128 for blgrp in blpairs :
113129 # Loop over blpairs in group and plot power spectrum for each one
114130 for blp in blgrp :
131+ # setup key and casting function
115132 key = (spw , blp , pol )
116133 if component == 'real' :
117- power = np .abs ( np . real ( uvp_plt . get_data ( key ))). T
134+ cast = np .real
118135 elif component == 'imag' :
119- power = np .abs ( np . imag ( uvp_plt . get_data ( key ))). T
136+ cast = np .imag
120137 elif component == 'abs' :
121- power = np .abs (uvp_plt .get_data (key )).T
138+ cast = np .abs
139+
140+ # get power array and repeat x array
141+ power = cast (uvp_plt .get_data (key ))
122142
123- # flag spectra that have zero integration
143+ # flag records that have zero integration
124144 flags = np .isclose (uvp_plt .get_integrations (key ), 0.0 )
125- power [:, flags ] = np .nan
145+ power [flags ] = np .nan
146+
147+ # get errs if requessted
148+ if error is not None and hasattr (uvp_plt , 'stats_array' ):
149+ if error in uvp_plt .stats_array :
150+ errs = uvp_plt .get_stats (error , key )
151+ errs [flags ] = np .nan
152+
153+ # iterate over integrations per blp
154+ for i in range (power .shape [0 ]):
155+ # get y data
156+ y = power [i ]
157+
158+ # plot elements
159+ cax = None
160+ if lines :
161+ cax , = ax .plot (x , np .abs (y ), label = "%s" % str (key ), marker = 'None' , ** kwargs )
162+
163+ if markers :
164+ if cax is None :
165+ c = None
166+ else :
167+ c = cax .get_color ()
168+ # plot positive w/ filled circles
169+ cax , = ax .plot (x [y >= 0 ], np .abs (y [y >= 0 ]), c = c , ls = 'None' , marker = 'o' ,
170+ markerfacecolor = c , markeredgecolor = c , ** kwargs )
171+ # plot negative w/ unfilled circles
172+ c = cax .get_color ()
173+ cax , = ax .plot (x [y < 0 ], np .abs (y [y < 0 ]), c = c , ls = 'None' , marker = 'o' ,
174+ markerfacecolor = 'None' , markeredgecolor = c , ** kwargs )
175+
176+ if error is not None and hasattr (uvp_plt , 'stats_array' ):
177+ if error in uvp_plt .stats_array :
178+ if cax is None :
179+ c = None
180+ else :
181+ c = cax .get_color ()
182+ cax = ax .errorbar (x , np .abs (y ), fmt = 'none' , ecolor = c , yerr = cast (errs [i ]), ** kwargs )
183+ else :
184+ raise KeyError ("Error variable '%s' not found in stats_array of UVPSpec object." % error )
126185
127- ax .plot (x , power , label = "%s" % str (key ))
128-
129186 # If blpairs were averaged, only the first blpair in the group
130187 # exists any more (so skip the rest)
131188 if average_blpairs : break
@@ -329,18 +386,20 @@ def delay_waterfall(uvp, blpairs, spw, pol, component='real', average_blpairs=Fa
329386 Nkeys = len (waterfall )
330387 Nside = int (np .ceil (np .sqrt (Nkeys )))
331388 fig , axes = plt .subplots (Nside , Nside , figsize = figsize )
389+
332390 # Ensure axes is an ndarray
333391 if isinstance (axes , matplotlib .axes ._subplots .Axes ):
334392 axes = np .array ([[axes ]])
335393 if isinstance (axes , list ):
336394 axes = np .array (axes )
337- # ensure its 2D and get side lengths
395+
396+ # Ensure its 2D and get side lengths
338397 if axes .ndim == 1 :
339398 axes = axes [:, None ]
340399 assert axes .ndim == 2 , "input axes must have ndim == 2"
341400 Nvert , Nhorz = axes .shape
342401
343- # get LST range: setting y-ticks is tricky due to LST wrapping...
402+ # Get LST range: setting y-ticks is tricky due to LST wrapping...
344403 y = uvp_plt .lst_avg_array [uvp_plt .key_to_indices (waterfall .keys ()[0 ])[1 ]]
345404 if lst_in_hrs :
346405 lst_units = "Hr"
@@ -369,7 +428,7 @@ def delay_waterfall(uvp, blpairs, spw, pol, component='real', average_blpairs=Fa
369428 psunits = psunits .replace ("beam normalization not specified" ,
370429 r"{\rm unnormed}" )
371430
372- # iterate over waterfall keys
431+ # Iterate over waterfall keys
373432 keys = waterfall .keys ()
374433 k = 0
375434 for i in range (Nvert ):
@@ -402,7 +461,7 @@ def delay_waterfall(uvp, blpairs, spw, pol, component='real', average_blpairs=Fa
402461 # configure left-column plots
403462 if j == 0 :
404463 # set yticks
405- ax .set_yticks (np .arange (Ny // Ny_thin + 1 ) )
464+ ax .set_yticks (np .arange (Ny )[:: Ny_thin ] )
406465 ax .set_yticklabels (y [::Ny_thin ])
407466 ax .set_ylabel (r"LST [{}]" .format (lst_units ), fontsize = 16 )
408467 else :
@@ -428,7 +487,8 @@ def delay_waterfall(uvp, blpairs, spw, pol, component='real', average_blpairs=Fa
428487 units = "$%sP(k_\parallel)$ $[%s]$" % (logunits , psunits )
429488
430489 spwrange = np .around (np .array (uvp_plt .get_spw_ranges ()[spw ][:2 ]) / 1e6 , 2 )
431- axes [0 ][0 ].get_figure ().suptitle ("{}\n {} polarization | {} -- {} MHz" .format (units , pol , * spwrange ), y = 1.03 , fontsize = 14 )
490+ axes [0 ][0 ].get_figure ().suptitle ("{}\n {} polarization | {} -- {} MHz" .format (units , pol , * spwrange ),
491+ y = 1.03 , fontsize = 14 )
432492
433493 # Return Axes
434494 if new_plot :
0 commit comments