def __init__(self, fields: Volume_T, max_dist: Number_T = 0.1): # Process data type self.dtype = get_dtype(fields[0]) # Process time t_arr = np.array( [time.mktime(i.scan_time.timetuple()) for i in fields]) if (t_arr.max() - t_arr.min()) / 60 > 10: raise RadarCalculationError( "Time difference of input data should not exceed 10 minutes") mean_time = t_arr.mean() mean_dtime = datetime.datetime(*time.localtime(int(mean_time))[:6]) time_increment = 10 time_rest = mean_dtime.minute % time_increment if time_rest > time_increment / 2: mean_dtime += datetime.timedelta(minutes=(time_increment - time_rest)) else: mean_dtime -= datetime.timedelta(minutes=time_rest) self.scan_time = mean_dtime self.lon_ravel = np.hstack( [i["longitude"].values.ravel() for i in fields]) self.lat_ravel = np.hstack( [i["latitude"].values.ravel() for i in fields]) self.data_ravel = np.ma.hstack( [i[self.dtype].values.ravel() for i in fields]) self.dist_ravel = np.hstack([ np.broadcast_to(i["distance"], i["longitude"].shape).ravel() for i in fields ]) self.tree = KDTree(np.dstack((self.lon_ravel, self.lat_ravel))[0]) self.md = max_dist self.attr = fields[0].attrs.copy()
def __init__(self, r_list: Volume_T): el = [i.elevation for i in r_list] if len(el) != len(set(el)): self.rl = list() el_list = list() for data in r_list: if data.elevation not in el_list: self.rl.append(data) el_list.append(data.elevation) else: self.rl = r_list self.dtype = get_dtype(r_list[0]) self.x, self.y, self.h, self.r = self._geocoor() self.attrs = r_list[0].attrs
def __init__(self, data: Dataset, fig: Optional[Any] = None, norm: Optional[Any] = None, cmap: Optional[Any] = None, nlabel: Optional[int] = None, label: Optional[List[str]] = None, dpi: Number_T = 350, highlight: Optional[Union[str, List[str]]] = None, coastline: bool = False, extent: Optional[List[Number_T]] = None, section: Optional[Dataset] = None, style: str = "black", add_city_names: bool = False, plot_labels: bool = True, **kwargs): self.data = data self.dtype = get_dtype(data) self.settings = { "cmap": cmap, "norm": norm, "nlabel": nlabel, "label": label, "highlight": highlight, "coastline": coastline, "path_customize": False, "extent": extent, "slice": section, "style": style, "add_city_names": add_city_names, "plot_labels": plot_labels, "is_inline": is_inline(), } if fig is None: self.fig = setup_plot(dpi, style=style) else: self.fig = fig # avoid in-place modification self.text_pos = TEXT_AXES_POS.copy() self.cbar_pos = CBAR_POS.copy() self._plot_ctx = dict() self.rf_flag = "RF" in data self._fig_init = False self._plot(**kwargs) if is_inline(): # In inline mode, figure will not be dynamically changed # call this action at initialization self._text_before_save()
def __init__( self, data: Dataset, hlim: int = 15, interpolate: bool = True, figsize: tuple = (10, 5), ): # TODO: Use context manager to control style plt.style.use("dark_background") self.data = data self.dtype = get_dtype(data) self.settings = { "hlim": hlim, "interp": interpolate, "figsize": figsize, } self.rhi_flag = "azimuth" in data.attrs self._plot()
def plot_cross_section( self, data: Dataset, ymax: Optional[int] = None, linecolor: Optional[str] = None, interpolate: bool = True, ): # May add check to ensure the data is slice data r"""Plot cross section data below the PPI plot.""" if self.settings["is_inline"] and self._fig_init: raise RuntimeError( "Adding cross section dynamically is not supported in" "inline backend, add section keyword when initializing PPI instead." ) if not linecolor: if self.settings["style"] == "black": linecolor = "white" elif self.settings["style"] == "white": linecolor = "black" self.settings["slice"] = data # The axes to plot c-section is below the main axes # the height of it is a quarter of the height of main axes # so the positions of the figure, the main axes, the colorbar axes # should be adjusted accordingly. # TODO: remove hardcode and calculate positions automatically self.fig.set_size_inches(10, 10) self.geoax.set_position([0, 0.2, 0.8, 0.8]) ax2 = self.fig.add_axes([0, 0.01, 0.8, 0.17]) # transform coordinates self.text_pos[1] = self.text_pos[1] * 0.8 + 0.2 self.text_pos[3] = self.text_pos[3] * 0.8 self.cbar_pos[1] = self.cbar_pos[1] * 0.8 + 0.2 self.cbar_pos[3] = self.cbar_pos[3] * 0.8 ax2.yaxis.set_ticks_position("right") ax2.set_xticks([]) dtype = get_dtype(data) sl = data[dtype].values if dtype == "REF": # visualization improvement for reflectivity sl[np.isnan(sl)] = -0.1 xcor = data["x_cor"] ycor = data["y_cor"] cmap = sec_plot[dtype] norm = norm_plot[dtype] if interpolate: ax2.contourf(xcor, ycor, sl, 256, cmap=cmap, norm=norm) else: ax2.pcolormesh(xcor, ycor, sl, cmap=cmap, norm=norm) if ymax: ax2.set_ylim(0, ymax) else: ax2.set_ylim(0, 15) ax2.set_title("Start: {}N {}E".format(data.start_lat, data.start_lon) + " End: {}N {}E".format(data.end_lat, data.end_lon)) self.geoax.plot( [data.start_lon, data.end_lon], [data.start_lat, data.end_lat], marker="x", color=linecolor, transform=self.data_crs, zorder=5, )