unox.plotting ============= .. py:module:: unox.plotting Attributes ---------- .. autoapisummary:: unox.plotting.title_font_size Functions --------- .. autoapisummary:: unox.plotting.plot_extent unox.plotting.plot_lats_lons unox.plotting.map_ax unox.plotting.plot_var_maps unox.plotting.select_time unox.plotting.plot_run_analysis unox.plotting.plot_comparison unox.plotting.corr_plot unox.plotting.plot_epochs_logs unox.plotting.make_colorbar unox.plotting.plot_hist unox.plotting.compare_input_vars unox.plotting.plot_BaW unox.plotting.BaW_label Module Contents --------------- .. py:data:: title_font_size :value: 20 .. py:function:: plot_extent(dataset, **kwargs) Plot the geographic extent of a dataset. Create a Robinson projection map showing the min/max latitude and longitude of the dataset. :param dataset: The dataset for which to plot the latitude/longitude extent. :type dataset: `str`, `xarray.Dataset`, `xarray.DataArray` :param \*\*kwargs: Additional keyword arguments to pass to `uarray()`. :type \*\*kwargs: keyword arguments :returns: **fig** -- The figure object containing the plot. :rtype: `matplotlib.figure.Figure` .. rubric:: Examples >>> fig = plot_extent('inputfiles/no2_2019_JFM/no2_2019_JFM.nc') >>> fig = plot_extent('no2_2019_JFM', is_input_set=True) .. py:function:: plot_lats_lons(dataset, padding=0.1, **kwargs) Plot the latitude/longitude grid of a dataset. Create a checkerboard map showing the latitude and longitude resolution of the dataset. :param dataset: The dataset for which to plot the latitude and longitude grid. :type dataset: `str`, `xarray.Dataset`, `xarray.DataArray` :param padding: The padding (in a fraction of total extent) to add to the extent of the map. Default is `0.1`. :type padding: `float`, optional :param \*\*kwargs: Additional keyword arguments to pass to `uarray()`. :type \*\*kwargs: keyword arguments :returns: **fig** -- The figure object containing the plot. :rtype: `matplotlib.figure.Figure` .. rubric:: Examples >>> fig = plot_lats_lons('inputfiles/no2_2019_JFM/no2_2019_JFM.nc') >>> fig = plot_lats_lons('no2_2019_JFM', is_input_set=True) .. py:function:: map_ax(xr_arr, ax, plt_title=None, cmap=pplt.Colormap('Fire'), cbar_max=None, cbar_min=None, cb_ext='neither', padding=0.1, **kwargs) Plot a geographic map from an xarray DataArray. Create a map of the provided xarray DataArray on the given axes using the latitude and longitude coordinates from the data. :param xr_arr: The xarray data to plot. Must not have a time dimension. :type xr_arr: `xarray.DataArray` :param ax: The axes on which to plot the data. :type ax: `matplotlib.axes.Axes` :param plt_title: The title for the plot. Default is `None`. :type plt_title: `str`, optional :param cmap: The colormap to use for the plot. Default is `pplt.cm.Fire`. :type cmap: `matplotlib.colors.Colormap`, optional :param cbar_max: Maximum value for the colorbar. When `None`, it uses the max value in the data. Default is `None`. :type cbar_max: `float`, optional :param cbar_min: Minimum value for the colorbar. When `None`, it uses the min value in the data. Default is `None`. :type cbar_min: `float`, optional :param cb_ext: How to extend the ends of the colorbar. Can be `'neither'`, `'both'`, `'min'`, or `'max'`. Default is `'neither'`. :type cb_ext: `str`, optional :param padding: The padding (fraction of total extent) to add to the map extent. Default is `0.1`. :type padding: `float`, optional :param \*\*kwargs: Additional keyword arguments accepted to facilitate wrapper functions. :type \*\*kwargs: keyword arguments :returns: * **this_map_ax** (`matplotlib.axes.Axes`) -- The axes object containing the plot. * **clrbar_label** (`str`) -- The label for the colorbar containing the variable name and units. .. rubric:: Examples >>> import proplot as pplt >>> fig, axs = pplt.subplots(nrows=1, ncols=2, proj='cyl') >>> this_xr = uarray('no2_2019_JFM', is_input_set=True).xr['no2'] >>> this_xr = this_xr.sel(time='2019-01-02').squeeze(drop=True) >>> this_ax, cb_label = map_ax(this_xr, axs[0]) .. py:function:: plot_var_maps(dataset, vars=['nox'], restrict_lat_lon_to=None, ens_mem=None, avg_over=True, sum_over=False, add_title=True, add_clrbar=True, **kwargs) Plot maps for one or more variables in a dataset. A wrapper around `map_ax()` that creates a map for each specified variable. :param dataset: The dataset for which to plot the specified variables. :type dataset: `uarray`, `str`, `xarray.Dataset`, `xarray.DataArray` :param vars: The name(s) of the variable(s) to plot from the dataset. Default is `['nox']`. :type vars: `str`, `list`, optional :param restrict_lat_lon_to: Path to a netCDF file to restrict the latitude and longitude range. If `None`, the entire dataset is used. Default is `None`. :type restrict_lat_lon_to: `str`, `xr.DataArray`, `None`, optional :param ens_mem: The ID of the ensemble member to plot. If `None`, the dataset is assumed not to have multiple ensemble members. Default is `None`. :type ens_mem: `int`, `None`, optional :param avg_over: Whether to average over all time steps. Cannot be `True` at the same time as `sum_over`. Default is `True`. :type avg_over: `bool`, optional :param sum_over: Whether to sum over all time steps. Cannot be `True` at the same time as `avg_over`. Default is `False`. :type sum_over: `bool`, optional :param add_title: Whether to add a title to the figure. Default is `True`. :type add_title: `bool`, optional :param add_clrbar: Whether to add a colorbar to each subplot. Default is `True`. :type add_clrbar: `bool`, optional :param \*\*kwargs: Additional keyword arguments to pass to `uarray`, `select_time()`, `set_fig_row_col()`, and `map_ax()`. :type \*\*kwargs: keyword arguments :returns: **fig** -- The figure object containing the plot. :rtype: `matplotlib.figure.Figure` .. rubric:: Examples >>> fig = plot_var_maps('no2_example_run', is_predict=True, vars=['no2_pred'], datetime='2019-06-01', interval='30D', avg_over=True) .. py:function:: select_time(xr_data, start_date=None, end_date=None, interval=None, avg_over=False, sum_over=False, **kwargs) Select a time slice from an xarray dataset. Either select a single time slice, average over a time period, or sum over the entire available time dimension to return an xarray without a time dimension. :param xr_data: The xarray data to plot. Must have a time dimension. :type xr_data: `xarray.Dataset`, `xarray.DataArray` :param start_date: First date and time to select from the data file. Default is `None`. :type start_date: `str`, `None`, optional :param end_date: Last date and time to select from the data file. Default is `None`. :type end_date: `str`, `None`, optional :param interval: If provided and `end_date` is `None`, calculates `end_date` based on this interval. If a string, must be in the format `XT` where `X` is an integer and `T` is the unit (`D` for days, `M` for months, or `Y` for years). Default is `None`. :type interval: `str`, `numpy.timedelta64`, `None`, optional :param avg_over: Whether to average over all time steps. Cannot be `True` at the same time as `sum_over`. Default is `False`. :type avg_over: `bool`, optional :param sum_over: Whether to sum across all time steps. Cannot be `True` at the same time as `avg_over`. Default is `False`. :type sum_over: `bool`, optional :param \*\*kwargs: Additional keyword arguments accepted to facilitate wrapper functions. :type \*\*kwargs: keyword arguments :returns: * **xr_sel_time** (`xarray.Dataset`, `xarray.DataArray`) -- The input xarray over the specified time interval. If either `avg_over` or `sum_over` is `True`, the return will not have a time dimension. * **title_segment** (`str`) -- A segment of the title string for the plot with time information. .. rubric:: Examples >>> xr_data = uarray('no2_2019_JFM', is_input_set=True).xr >>> xr_sel_time, title_segment = select_time(xr_data, datetime='2019-01-15') .. py:function:: plot_run_analysis(dataset, start_date='2019-01-02', interval='1Y', avg_over=True, restrict_lat_lon_to=None, ens_mem=None, add_corr_plots=True, stage1_only=False, clr_bar_scale=0.5, clr_map=pplt.Colormap('Balance'), **kwargs) Compare a model run to the truth with maps and optional correlation plots. Create a set of maps comparing the truth and model predictions (stages 1 and 2), and optionally add correlation plots. If both stages and correlations are plotted, the figure will have 9 subplots: 1. 'Truth' map 2. Stage 1 prediction map 3. Stage 2 prediction map 4. Difference between 'Truth' and Stage 1 map 5. Difference between 'Truth' and Stage 2 map 6. Difference between Stage 1 and Stage 2 map 7. Correlation plot between 'Truth' and Stage 1 8. Correlation plot between 'Truth' and Stage 2 9. Correlation plot between Stage 1 and Stage 2 :param dataset: The dataset for which to make comparison maps. Must be a predictions dataset. :type dataset: `str`, `xarray.Dataset`, `xarray.DataArray`, `uarray` :param start_date: First date and time to select from the data file. Default is `None`. :type start_date: `str`, `None`, optional :param interval: If provided and `end_date` is `None`, calculate `end_date` based on this interval. If a string, it must be in the format `XT` where `X` is an integer and `T` is the unit (`D`, `M`, or `Y`). Default is `None`. :type interval: `str`, `numpy.timedelta64`, `None`, optional :param avg_over: Whether to average over all time steps. Default is `True`. :type avg_over: `bool`, optional :param restrict_lat_lon_to: Path to a netCDF file to restrict the latitude and longitude range. If `None`, the entire dataset is used. Default is `None`. :type restrict_lat_lon_to: `str`, `xr.DataArray`, `None`, optional :param ens_mem: The ID of the ensemble member to plot. If `None`, the dataset is assumed not to have multiple ensemble members. Default is `None`. :type ens_mem: `int`, `None`, optional :param add_corr_plots: Whether to add a row of correlation plots to the figure. Default is `True`. :type add_corr_plots: `bool`, optional :param stage1_only: If `True`, produce graphs only for stage 1. If `False`, produce graphs for both stage 1 and stage 2. Default is `False`. :type stage1_only: `bool`, optional :param clr_bar_scale: Scale factor for the colorbar, between 0 and 1. Default is `0.5`. :type clr_bar_scale: `float`, optional :param clr_map: The colormap to use for the map plots. Default is `pplt.cm.Balance`. :type clr_map: `matplotlib.colors.Colormap`, optional :param \*\*kwargs: Additional keyword arguments to pass to `select_time()`, `map_ax()`, and `corr_plot()`. :type \*\*kwargs: keyword arguments :returns: **fig** -- The figure object containing the plots. :rtype: `matplotlib.figure.Figure` .. rubric:: Examples >>> fig = plot_run_analysis('no2_example_run', year=2019, datetime='2019-01-02', ... avg_over='364D', restrict_lat_lon_to='../datafiles/sample_data/nox_2019_t106_US.nc', add_corr_plots=True) .. py:function:: plot_comparison(a_xr_arr, b_xr_arr, ax=None, plt_title=None, a_label=None, b_label=None, cmap=pplt.Colormap('viridis'), set_under_val=1, hist_params={'bins': 100, 'vmax': 1000, 'vmin': 10}, log_scale=True, **kwargs) Plot a comparison of two arrays using a 2D histogram. Create a correlation plot between the values of the two provided arrays. :param a_xr_arr: The first array to compare. :type a_xr_arr: `xarray.DataArray`, `numpy.ndarray` :param b_xr_arr: The second array to compare. :type b_xr_arr: `xarray.DataArray`, `numpy.ndarray` :param ax: The axes on which to plot the data. If `None`, a new figure is created. Default is `None`. :type ax: `matplotlib.axes.Axes`, optional :param plt_title: The title for the plot. Default is `None`. :type plt_title: `str`, optional :param a_label: The label to use for the first array. :type a_label: `str`, optional :param b_label: The label to use for the second array. :type b_label: `str`, optional :param cmap: The colormap to use for the plot. Default is `pplt.cm.viridis`. :type cmap: `matplotlib.colors.Colormap`, optional :param set_under_val: The value below which the colormap is set to white. Default is `1`. :type set_under_val: `float`, optional :param hist_params: Parameters for the 2D histogram. Default is `{'bins': 100, 'vmax': 1000, 'vmin': 10}`. :type hist_params: `dict`, optional :param log_scale: Whether to use a logarithmic scale for the histogram. Default is `True`. :type log_scale: `bool`, optional :param \*\*kwargs: Additional keyword arguments accepted to facilitate wrapper functions. :type \*\*kwargs: keyword arguments :returns: * **fig** (`matplotlib.figure.Figure`) -- The figure object containing the plot. Returned if `ax` is `None`. * **q** (`QuadMesh`) -- The QuadMesh object created by the 2D histogram. Returned if `ax` is given. .. py:function:: corr_plot(dataset, x_vars=['pred'], y_vars=['truth'], axs=None, restrict_lat_lon_to=None, ens_mem=None, **kwargs) Create correlation plots between specified variables. Create a heatmap correlation plot with the specified variables on each axis using data from the given dataset, filtering by datetime, averaging period, and optional latitude/longitude restrictions. :param dataset: The dataset from which to get the data for the correlation plot. :type dataset: `str`, `uarray`, `xarray.Dataset`, `xarray.DataArray` :param x_vars: The variable(s) to plot on the x-axis. Can be `truth`, `pred`, `pred_s2`, or any variable in the dataset. Default is `['pred']`. :type x_vars: `list`, `str`, optional :param y_vars: The variable(s) to plot on the y-axis. Can be `truth`, `pred`, `pred_s2`, or any variable in the dataset. Default is `['truth']`. :type y_vars: `list`, `str`, optional :param axs: The axes on which to plot the data. If `None`, a new figure is created. Default is `None`. :type axs: `list`, `matplotlib.axes.Axes`, `None`, optional :param restrict_lat_lon_to: Path to a netCDF file to restrict the latitude and longitude range. If `None`, the entire dataset is used. Default is `None`. :type restrict_lat_lon_to: `str`, `xr.DataArray`, `None`, optional :param ens_mem: The ID of the ensemble member to plot. If `None`, the dataset is assumed not to have multiple ensemble members. Default is `None`. :type ens_mem: `int`, `None`, optional :param \*\*kwargs: Additional keyword arguments to pass to `select_time()` and `plot_comparison()`. :type \*\*kwargs: dict :returns: * **fig** (`matplotlib.figure.Figure`) -- If no axes were given, return the figure object containing the plot. * **fig_q** (`QuadMesh`) -- If axes were given, return the QuadMesh object created by the 2D histogram. .. rubric:: Examples >>> fig = corr_plot('no2_example_run', is_predict=True, x_ax='pred', y_ax='truth') .. py:function:: plot_epochs_logs(dataset, vars=None, axs=None, plt_title=None, **kwargs) Plot training epoch logs for a prediction dataset. Create a line plot showing how specified metrics changed across training epochs. :param dataset: The dataset for which to plot epoch logs. Must be a predictions dataset. :type dataset: `str`, `xarray.Dataset`, `xarray.DataArray`, `uarray` :param vars: The variables to plot. Each variable is plotted on its own axis. If `None`, all available variables are plotted. Default is `None` (which plots all variables). :type vars: `str`, `list`, `None`, optional :param axs: The axes on which to plot the data. If `None`, a new figure is created. Default is `None`. :type axs: `matplotlib.axes.Axes`, `None`, optional :param plt_title: The title for the plot. Default is `None`. :type plt_title: `str`, optional :param \*\*kwargs: Additional keyword arguments accepted to facilitate wrapper functions. :type \*\*kwargs: keyword arguments :returns: * **fig** (`matplotlib.figure.Figure`) -- The figure object containing the plot. Returned if `axs` is `None`. * **axs** (`matplotlib.axes.Axes`) -- The axes containing the plot. Returned if `axs` was provided. .. py:function:: make_colorbar(fig, cb_ax, cb_label, num_ticks=9, cb_loc='r', cb_extend='neither', **kwargs) Create a colorbar for the given figure and axis. :param fig: The figure on which to add the colorbar. :type fig: `matplotlib.figure.Figure` :param cb_ax: The geo quad mesh on which to add the colorbar. :type cb_ax: `cartopy.mpl.geocollection.GeoQuadMesh` :param cb_label: The label for the colorbar. :type cb_label: `str` :param num_ticks: The number of ticks for the colorbar. Default is `9`. :type num_ticks: `int`, optional :param cb_loc: The location of the colorbar. Default is `'r'`. :type cb_loc: `str`, optional :param cb_extend: How to extend the ends of the colorbar. Can be `'neither'`, `'both'`, `'min'`, or `'max'`. Default is `'neither'`. :type cb_extend: `str`, optional :param \*\*kwargs: Additional keyword arguments to pass to `colorbar()`, such as the `rows` tuple. :type \*\*kwargs: keyword arguments :returns: **cbar** -- The generated colorbar. :rtype: `matplotlib.colorbar.Colorbar` .. rubric:: Examples >>> fig, axs = pplt.subplots(nrows=3, ncols=3) >>> n_rows_maps = 2 >>> cbar = make_colorbar(fig, axs, cb_label='NOx emissions (kg/m2/s)', rows=(1, n_rows_maps)) .. py:function:: plot_hist(data_arrs, ax=None, n_bins=100, ax_label='NOx emissions (kg/m2/s)', ylabel='Frequency', plt_title=None, log_scale=False) Plot a histogram of one or more data arrays. Create a histogram of the given data on the provided axis, or create a new figure and axis if none is provided. Each array in `data_arrs` is plotted as a separate histogram. :param data_arrs: The array(s) to plot. :type data_arrs: `list`, `numpy.ndarray`, `xr.DataArray` :param ax: The axes on which to plot the histogram. If `None`, a new figure and axes are created. Default is `None`. :type ax: `matplotlib.axes.Axes`, `None`, optional :param n_bins: The number of bins to use for the histogram. Default is `100`. :type n_bins: `int`, optional :param ax_label: The label for the x-axis. Default is `'NOx emissions (kg/m2/s)'`. :type ax_label: `str`, optional :param ylabel: The label for the y-axis. Default is `'Frequency'`. :type ylabel: `str`, optional :param plt_title: The title of the plot. Default is `None`. :type plt_title: `str`, optional :param log_scale: If `True`, the y-axis will be set to a logarithmic scale. Default is `False`. :type log_scale: `bool`, optional :returns: **fig or ax** -- The figure or axes containing the histogram. :rtype: `matplotlib.figure.Figure` or `matplotlib.axes.Axes` .. rubric:: Examples >>> data_arr1 = uarray('nox_2019_JFM', is_input_set=True).xr['no2'].values >>> data_arr2 = uarray('nox_2019_JFM', is_input_set=True).xr['no2_s2'].values >>> fig = plot_hist(data_arr1) >>> fig, axs = pplt.subplots(nrows=2, ncols=1) >>> axs[0] = plot_hist([data_arr1, data_arr2], ax=axs[0], n_bins=50, plt_title='Histogram of NO2 emissions, both stages') .. py:function:: compare_input_vars(input_a_dict={'input_set': 'no2_2019_JFM', 'year': 2019, 'var': 'no2'}, input_b_dict={'input_set': 'no2_2019_JFM', 'year': 2019, 'var': 'no2_s2'}, abs_tolerance=2e-05, restrict_lat_lon_to=None) Compare two input variables and optionally plot their differences. :param input_a_dict: Dictionary containing the parameters for the first input variable. Must contain `'input_set'`, `'year'`, and `'var'`. :type input_a_dict: `dict`, optional :param input_b_dict: Dictionary containing the parameters for the second input variable. Must contain `'input_set'`, `'year'`, and `'var'`. :type input_b_dict: `dict`, optional :param abs_tolerance: The absolute tolerance for comparing the input files. Default is `2e-5`. :type abs_tolerance: `float`, optional :param restrict_lat_lon_to: Path to a netCDF file to restrict the latitude and longitude range. If `None`, the entire dataset is used. Default is `None`. :type restrict_lat_lon_to: `str`, `xr.DataArray`, `None`, optional :returns: * *None* -- If the input files match within the given tolerance. * **fig** (`matplotlib.figure.Figure`) -- If the input files differ more than the given tolerance, a figure is returned. .. rubric:: Examples >>> fig = compare_input_vars( ... { ... 'input_set': 'no2_2019_JFM', ... 'year': 2019, ... 'var': 'no2', ... }, ... { ... 'input_set': 'no2_2019_JFM', ... 'year': 2019, ... 'var': 'no2_s2', ... }, ... restrict_lat_lon_to='../datafiles/sample_data/nox_2019_t106_US.nc', ... ) .. py:function:: plot_BaW(vars, datasets, ds_kwargs=None, axs=None, violin=False, **kwargs) Plot box-and-whisker (or violin) plots for specified variables. Create a box-and-whisker plot (or optional violin plot) of the specified variables from one or more datasets. :param vars: The variable(s) to plot on the x-axis/axes. Can be `R2`, `RMSE`, or any variable in the dataset. :type vars: `list`, `str` :param datasets: The dataset(s) from which to get the data for the plot. :type datasets: `list`, `str`, `uarray`, `xarray.Dataset`, `xarray.DataArray` :param ds_kwargs: Dictionaries of keyword arguments to specify the format of each plot. Default is `None`. :type ds_kwargs: `list`, `dict`, optional :param axs: The axes on which to plot the data. If `None`, a new figure is created. Default is `None`. :type axs: `list`, `matplotlib.axes.Axes`, `None`, optional :param violin: Whether to make a violin plot instead of a box-and-whisker plot. Default is `False`. :type violin: `bool`, optional :param \*\*kwargs: Additional keyword arguments to pass to `set_fig_row_col()`. :type \*\*kwargs: dict :returns: * **fig** (`matplotlib.figure.Figure`) -- If no axes were provided, return the figure object containing the plot. * **axs** (`matplotlib.axes.Axes`) -- If axes were provided, return those axes with the plots on them. .. rubric:: Examples >>> fig = plot_BaW( ... ['R2', 'RMSE'], ... '_ZFI_ensemble_run', ... ds_kwargs=[ ... { ... 'is_predict': True, ... 'start_date': '2019-01-02', ... 'interval': '1Y', ... 'restrict_lat_lon_to': 'datafiles/sample_data/nox_2019_t106_US.nc', ... }, ... ] ... ) .. py:function:: BaW_label(u_arr, label_with=None, var=None, one_dataset=False, **kwargs) Assemble a label for a box-and-whisker plot. Construct a label for a box-and-whisker plot based on metadata from a `uarray`, the requested components in `label_with`, and any formatting kwargs. :param u_arr: The uarray object from which to derive label metadata. :type u_arr: `uarray` :param label_with: Components to include in the label (e.g., `['name', 'size']`). Default is `None`, which uses `['name', 'size']`. :type label_with: `list`, `None`, optional :param var: The variable name to use when computing label components like size. :type var: `str`, optional :param one_dataset: Whether the plot is for a single dataset. Default is `False`. :type one_dataset: `bool`, optional :param \*\*kwargs: Additional keyword arguments passed to `format_sci_notation()`. :type \*\*kwargs: dict :returns: The formatted label. :rtype: str .. rubric:: Examples >>> BaW_label( ... uarray('no2_example_run', is_predict=True), ... label_with=['name', 'size'], ... var='nox_pred', ... one_dataset=False, ... ) 'no2_example_run (n=4892160)'