Example #1
0
def _plot_inset_histogram_for_attributes_diagram(
        figure_object,
        num_examples_by_bin,
        bar_face_colour=DEFAULT_HISTOGRAM_FACE_COLOUR,
        bar_edge_colour=DEFAULT_HISTOGRAM_EDGE_COLOUR,
        bar_edge_width=DEFAULT_HISTOGRAM_EDGE_WIDTH):
    """Plots forecast histogram inset in attributes diagram.

    For more on the attributes diagram, see Hsu and Murphy (1986).

    B = number of forecast bins

    :param figure_object: Instance of `matplotlib.figure.Figure`.
    :param num_examples_by_bin: length-B numpy array with number of examples in
        each forecast bin.
    :param bar_face_colour: Colour (in any format accepted by
        `matplotlib.colors`) for interior of histogram bars.
    :param bar_edge_colour: Colour for edge of histogram bars.
    :param bar_edge_width: Width for edge of histogram bars.
    """

    error_checking.assert_is_integer_numpy_array(num_examples_by_bin)
    error_checking.assert_is_numpy_array(num_examples_by_bin, num_dimensions=1)
    error_checking.assert_is_geq_numpy_array(num_examples_by_bin, 0)
    num_forecast_bins = len(num_examples_by_bin)
    error_checking.assert_is_geq(num_forecast_bins, 2)

    example_frequency_by_bin = (num_examples_by_bin.astype(float) /
                                numpy.sum(num_examples_by_bin))

    forecast_bin_edges = numpy.linspace(0., 1., num=num_forecast_bins + 1)
    forecast_bin_width = forecast_bin_edges[1] - forecast_bin_edges[0]
    forecast_bin_centers = forecast_bin_edges[:-1] + forecast_bin_width / 2

    inset_axes_object = figure_object.add_axes([
        INSET_HISTOGRAM_LEFT_EDGE, INSET_HISTOGRAM_BOTTOM_EDGE,
        INSET_HISTOGRAM_WIDTH, INSET_HISTOGRAM_HEIGHT
    ])

    inset_axes_object.bar(
        forecast_bin_centers,
        example_frequency_by_bin,
        forecast_bin_width,
        color=plotting_utils.colour_from_numpy_to_tuple(bar_face_colour),
        edgecolor=plotting_utils.colour_from_numpy_to_tuple(bar_edge_colour),
        linewidth=bar_edge_width)

    max_y_tick_value = rounder.floor_to_nearest(
        1.05 * numpy.max(example_frequency_by_bin),
        INSET_HISTOGRAM_Y_TICK_SPACING)
    num_y_ticks = 1 + int(
        numpy.round(max_y_tick_value / INSET_HISTOGRAM_Y_TICK_SPACING))
    y_tick_values = numpy.linspace(0., max_y_tick_value, num=num_y_ticks)

    pyplot.xticks(INSET_HISTOGRAM_X_TICKS, axes=inset_axes_object)
    pyplot.yticks(y_tick_values, axes=inset_axes_object)
    inset_axes_object.set_xlim(0., 1.)
    inset_axes_object.set_ylim(0., 1.05 * numpy.max(example_frequency_by_bin))
Example #2
0
def _predictor_name_to_face_colour(predictor_name):
    """Converts predictor name to face colour for bar graph.

    :param predictor_name: Predictor name (string).
    :return: face_colour: Colour as length-3 tuple.
    """

    if predictor_name in SOUNDING_PREDICTOR_NAMES:
        return plotting_utils.colour_from_numpy_to_tuple(SOUNDING_COLOUR)

    return plotting_utils.colour_from_numpy_to_tuple(DEFAULT_FACE_COLOUR)
Example #3
0
def _plot_inset_histogram_for_attributes_diagram(figure_object,
                                                 num_examples_by_bin):
    """Plots forecast histogram inset in attributes diagram.

    For more on the attributes diagram, see Hsu and Murphy (1986).

    B = number of forecast bins

    :param figure_object: Instance of `matplotlib.figure.Figure`.
    :param num_examples_by_bin: length-B numpy array with number of examples in
        each forecast bin.
    """

    error_checking.assert_is_integer_numpy_array(num_examples_by_bin)
    error_checking.assert_is_numpy_array(num_examples_by_bin, num_dimensions=1)
    error_checking.assert_is_geq_numpy_array(num_examples_by_bin, 0)
    num_forecast_bins = len(num_examples_by_bin)
    error_checking.assert_is_geq(num_forecast_bins, 2)

    example_frequency_by_bin = (num_examples_by_bin.astype(float) /
                                numpy.sum(num_examples_by_bin))

    forecast_bin_edges = numpy.linspace(0., 1., num=num_forecast_bins + 1)
    forecast_bin_width = forecast_bin_edges[1] - forecast_bin_edges[0]
    forecast_bin_centers = forecast_bin_edges[:-1] + forecast_bin_width / 2

    inset_axes_object = figure_object.add_axes([
        HISTOGRAM_LEFT_EDGE, HISTOGRAM_BOTTOM_EDGE, HISTOGRAM_AXES_WIDTH,
        HISTOGRAM_AXES_HEIGHT
    ])

    inset_axes_object.bar(
        forecast_bin_centers,
        example_frequency_by_bin,
        forecast_bin_width,
        color=plotting_utils.colour_from_numpy_to_tuple(BAR_FACE_COLOUR),
        edgecolor=plotting_utils.colour_from_numpy_to_tuple(BAR_EDGE_COLOUR),
        linewidth=BAR_EDGE_WIDTH)

    max_y_tick_value = rounder.floor_to_nearest(
        1.05 * numpy.max(example_frequency_by_bin), HISTOGRAM_Y_SPACING)
    num_y_ticks = 1 + int(numpy.round(max_y_tick_value / HISTOGRAM_Y_SPACING))
    y_tick_values = numpy.linspace(0., max_y_tick_value, num=num_y_ticks)

    pyplot.xticks(HISTOGRAM_X_VALUES, axes=inset_axes_object)
    pyplot.yticks(y_tick_values, axes=inset_axes_object)
    inset_axes_object.set_xlim(0., 1.)
    inset_axes_object.set_ylim(0., 1.05 * numpy.max(example_frequency_by_bin))

    inset_axes_object.set_title('Forecast histogram', fontsize=20)
Example #4
0
def _label_bars(axes_object, y_tick_coords, y_tick_strings, significant_flags):
    """Labels bars in graph.

    J = number of bars

    :param axes_object: Will plot on these axes (instance of
        `matplotlib.axes._subplots.AxesSubplot`).
    :param y_tick_coords: length-J numpy array with y-coordinates of bars.
    :param y_tick_strings: length-J list of labels.
    :param significant_flags: length-J numpy array of Boolean flags.  If
        significant_flags[i] = True, the [i]th step has a significantly
        different cost than the [i + 1]th step.
    """

    this_colour = plotting_utils.colour_from_numpy_to_tuple(BAR_TEXT_COLOUR)

    for j in range(len(y_tick_coords)):
        y_tick_strings[j] = y_tick_strings[j].replace(
            'Surface geopotential height', 'Orographic height')

        axes_object.text(
            0.,
            y_tick_coords[j],
            '      ' + y_tick_strings[j],
            color=this_colour,
            horizontalalignment='left',
            verticalalignment='center',
            fontweight='bold' if significant_flags[j] else 'normal',
            fontsize=BAR_FONT_SIZE)
Example #5
0
def plot_storm_outlines(
        storm_object_table, axes_object, basemap_object,
        line_width=DEFAULT_POLYGON_WIDTH, line_colour=DEFAULT_POLYGON_COLOUR,
        line_style='solid'):
    """Plots all storm objects in the table (as unfilled polygons).

    :param storm_object_table: See doc for `storm_tracking_io.write_file`.
    :param axes_object: Will plot on these axes (instance of
        `matplotlib.axes._subplots.AxesSubplot`).
    :param basemap_object: Will use this object (instance of
        `mpl_toolkits.basemap.Basemap`) to convert between x-y and lat-long
        coords.
    :param line_width: Width of each polygon.
    :param line_colour: Colour of each polygon.
    :param line_style: Line style for each polygon.
    """

    line_colour_tuple = plotting_utils.colour_from_numpy_to_tuple(line_colour)
    num_storm_objects = len(storm_object_table.index)

    for i in range(num_storm_objects):
        this_vertex_dict_latlng = polygons.polygon_object_to_vertex_arrays(
            storm_object_table[tracking_utils.LATLNG_POLYGON_COLUMN].values[i]
        )

        these_x_coords_metres, these_y_coords_metres = basemap_object(
            this_vertex_dict_latlng[polygons.EXTERIOR_X_COLUMN],
            this_vertex_dict_latlng[polygons.EXTERIOR_Y_COLUMN]
        )

        axes_object.plot(
            these_x_coords_metres, these_y_coords_metres,
            color=line_colour_tuple, linestyle=line_style, linewidth=line_width
        )
Example #6
0
def plot_storm_centroids(storm_object_table,
                         axes_object,
                         basemap_object,
                         marker_type=DEFAULT_CENTROID_MARKER_TYPE,
                         marker_colour=DEFAULT_CENTROID_COLOUR,
                         marker_size=DEFAULT_CENTROID_MARKER_SIZE):
    """Plots all storm centroids in the table (as markers).

    :param storm_object_table: See doc for `plot_storm_outlines`.
    :param axes_object: Same.
    :param basemap_object: Same.
    :param marker_type: Marker type for storm centroids (in any format accepted
        by `matplotlib.lines`).
    :param marker_colour: Colour for storm centroids.
    :param marker_size: Marker size for storm centroids.
    """

    marker_colour_tuple = plotting_utils.colour_from_numpy_to_tuple(
        marker_colour)

    x_coords_metres, y_coords_metres = basemap_object(
        storm_object_table[tracking_utils.CENTROID_LONGITUDE_COLUMN].values,
        storm_object_table[tracking_utils.CENTROID_LATITUDE_COLUMN].values)

    axes_object.plot(x_coords_metres,
                     y_coords_metres,
                     linestyle='None',
                     marker=marker_type,
                     markerfacecolor=marker_colour_tuple,
                     markeredgecolor=marker_colour_tuple,
                     markersize=marker_size,
                     markeredgewidth=0)
Example #7
0
def plot_bootstrapped_reliability_curve(
        axes_object,
        ci_bottom_dict,
        ci_mean_dict,
        ci_top_dict,
        line_colour=DEFAULT_RELIABILITY_COLOUR,
        line_width=DEFAULT_RELIABILITY_WIDTH,
        perfect_line_colour=DEFAULT_PERFECT_RELIABILITY_COLOUR,
        perfect_line_width=DEFAULT_PERFECT_RELIABILITY_WIDTH):
    """Bootstrapped version of plot_reliability_curve.

    B = number of bins (separated by forecast probability)

    :param axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    :param ci_bottom_dict: Dictionary with the following keys,
        representing the bottom of the confidence interval.
    ci_bottom_dict['mean_forecast_by_bin']: length-B numpy array of mean
        forecast probabilities.
    ci_bottom_dict['event_frequency_by_bin']: length-B numpy array of
        conditional event frequencies.

    :param ci_mean_dict: Same but for mean of confidence interval.
    :param ci_top_dict: Same but for top of confidence interval.
    :param line_colour: Colour for reliability curve (mean of confidence
        interval; in any format accepted by `matplotlib.colors`).  The rest of
        the confidence interval will be shaded with the same colour but 50%
        opacity.
    :param line_width: Line width for reliability curve (mean of confidence
        interval).
    :param perfect_line_colour: Colour of reference line (perfect reliability
        curve).
    :param perfect_line_width: Width of reference line.
    """

    plot_reliability_curve(
        axes_object=axes_object,
        mean_forecast_by_bin=ci_mean_dict[model_eval.MEAN_FORECAST_BY_BIN_KEY],
        event_frequency_by_bin=ci_mean_dict[model_eval.EVENT_FREQ_BY_BIN_KEY],
        line_colour=line_colour,
        line_width=line_width,
        perfect_line_colour=perfect_line_colour,
        perfect_line_width=perfect_line_width)

    polygon_object = _confidence_interval_to_polygon(
        x_coords_bottom=ci_bottom_dict[model_eval.MEAN_FORECAST_BY_BIN_KEY],
        y_coords_bottom=ci_bottom_dict[model_eval.EVENT_FREQ_BY_BIN_KEY],
        x_coords_top=ci_top_dict[model_eval.MEAN_FORECAST_BY_BIN_KEY],
        y_coords_top=ci_top_dict[model_eval.EVENT_FREQ_BY_BIN_KEY])

    polygon_colour = matplotlib.colors.to_rgba(
        plotting_utils.colour_from_numpy_to_tuple(line_colour),
        TRANSPARENCY_FOR_CONFIDENCE_INTERVAL)

    polygon_patch = PolygonPatch(polygon_object,
                                 lw=0,
                                 ec=polygon_colour,
                                 fc=polygon_colour)

    axes_object.add_patch(polygon_patch)
Example #8
0
def plot_bootstrapped_performance_diagram(
        axes_object,
        ci_bottom_dict,
        ci_mean_dict,
        ci_top_dict,
        line_colour=DEFAULT_PERFORMANCE_COLOUR,
        line_width=DEFAULT_PERFORMANCE_WIDTH,
        bias_line_colour=DEFAULT_FREQ_BIAS_COLOUR,
        bias_line_width=DEFAULT_FREQ_BIAS_WIDTH):
    """Bootstrapped version of plot_performance_diagram.

    :param axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    :param ci_bottom_dict: Dictionary with the following keys,
        representing the bottom of the confidence interval.
    ci_bottom_dict['pod_by_threshold']: length-T numpy array of POD
        values (probability of detection).
    ci_bottom_dict['success_ratio_by_threshold']: length-T numpy array of
        success ratios.

    :param ci_mean_dict: Same but for mean of confidence interval.
    :param ci_top_dict: Same but for top of confidence interval.
    :param line_colour: Colour for performance curve (mean of confidence
        interval; in any format accepted by `matplotlib.colors`).  The rest of
        the confidence interval will be shaded with the same colour but 50%
        opacity.
    :param line_width: Line width for performance curve (mean of confidence
        interval).
    :param bias_line_colour: Colour of contour lines for frequency bias.
    :param bias_line_width: Width of contour lines for frequency bias.
    """

    plot_performance_diagram(
        axes_object=axes_object,
        pod_by_threshold=ci_mean_dict[model_eval.POD_BY_THRESHOLD_KEY],
        success_ratio_by_threshold=ci_mean_dict[
            model_eval.SR_BY_THRESHOLD_KEY],
        line_colour=line_colour,
        line_width=line_width,
        bias_line_colour=bias_line_colour,
        bias_line_width=bias_line_width)

    polygon_object = _confidence_interval_to_polygon(
        x_coords_bottom=ci_bottom_dict[model_eval.SR_BY_THRESHOLD_KEY],
        y_coords_bottom=ci_bottom_dict[model_eval.POD_BY_THRESHOLD_KEY],
        x_coords_top=ci_top_dict[model_eval.SR_BY_THRESHOLD_KEY],
        y_coords_top=ci_top_dict[model_eval.POD_BY_THRESHOLD_KEY],
        for_performance_diagram=True)

    polygon_colour = matplotlib.colors.to_rgba(
        plotting_utils.colour_from_numpy_to_tuple(line_colour),
        TRANSPARENCY_FOR_CONFIDENCE_INTERVAL)

    polygon_patch = PolygonPatch(polygon_object,
                                 lw=0,
                                 ec=polygon_colour,
                                 fc=polygon_colour)

    axes_object.add_patch(polygon_patch)
Example #9
0
def plot_bootstrapped_roc_curve(axes_object,
                                ci_bottom_dict,
                                ci_mean_dict,
                                ci_top_dict,
                                line_colour=DEFAULT_ROC_COLOUR,
                                line_width=DEFAULT_ROC_WIDTH,
                                random_line_colour=DEFAULT_RANDOM_ROC_COLOUR,
                                random_line_width=DEFAULT_RANDOM_ROC_WIDTH):
    """Bootstrapped version of plot_roc_curve.

    T = number of probability thresholds in curve

    :param axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    :param ci_bottom_dict: Dictionary with the following keys, representing the
        bottom of the confidence interval.
    ci_bottom_dict['pod_by_threshold']: length-T numpy array of POD values
        (probability of detection).
    ci_bottom_dict['pofd_by_threshold']: length-T numpy array of POFD values
        (probability of false detection).

    :param ci_mean_dict: Same but for mean of confidence interval.
    :param ci_top_dict: Same but for top of confidence interval.
    :param line_colour: Colour for ROC curve (mean of confidence interval; in
        any format accepted by `matplotlib.colors`).  The rest of the confidence
        interval will be shaded with the same colour but 50% opacity.
    :param line_width: Line width for ROC curve (mean of confidence interval).
    :param random_line_colour: Colour of reference line (ROC curve for a random
        predictor).
    :param random_line_width: Width of reference line.
    """

    plot_roc_curve(
        axes_object=axes_object,
        pod_by_threshold=ci_mean_dict[model_eval.POD_BY_THRESHOLD_KEY],
        pofd_by_threshold=ci_mean_dict[model_eval.POFD_BY_THRESHOLD_KEY],
        line_colour=line_colour,
        line_width=line_width,
        random_line_colour=random_line_colour,
        random_line_width=random_line_width)

    polygon_object = _confidence_interval_to_polygon(
        x_coords_bottom=ci_bottom_dict[model_eval.POFD_BY_THRESHOLD_KEY],
        y_coords_bottom=ci_bottom_dict[model_eval.POD_BY_THRESHOLD_KEY],
        x_coords_top=ci_top_dict[model_eval.POFD_BY_THRESHOLD_KEY],
        y_coords_top=ci_top_dict[model_eval.POD_BY_THRESHOLD_KEY])

    polygon_colour = matplotlib.colors.to_rgba(
        plotting_utils.colour_from_numpy_to_tuple(line_colour),
        TRANSPARENCY_FOR_CONFIDENCE_INTERVAL)

    polygon_patch = PolygonPatch(polygon_object,
                                 lw=0,
                                 ec=polygon_colour,
                                 fc=polygon_colour)

    axes_object.add_patch(polygon_patch)
Example #10
0
def plot_bootstrapped_roc_curve(axes_object,
                                ci_bottom_dict,
                                ci_mean_dict,
                                ci_top_dict,
                                line_colour=ROC_CURVE_COLOUR,
                                plot_background=True):
    """Bootstrapped version of plot_roc_curve.

    T = number of probability thresholds in curve

    :param axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    :param ci_bottom_dict: Dictionary with the following keys, representing the
        bottom of the confidence interval.
    ci_bottom_dict['pod_by_threshold']: length-T numpy array of POD values
        (probability of detection).
    ci_bottom_dict['pofd_by_threshold']: length-T numpy array of POFD values
        (probability of false detection).

    :param ci_mean_dict: Same but for mean of confidence interval.
    :param ci_top_dict: Same but for top of confidence interval.
    :param line_colour: See doc for `plot_roc_curve`.
    :param plot_background: Same.
    :return: line_handle: Same.
    """

    line_handle = plot_roc_curve(
        axes_object=axes_object,
        pod_by_threshold=ci_mean_dict[model_eval.POD_BY_THRESHOLD_KEY],
        pofd_by_threshold=ci_mean_dict[model_eval.POFD_BY_THRESHOLD_KEY],
        line_colour=line_colour,
        plot_background=plot_background)

    polygon_object = _confidence_interval_to_polygon(
        x_coords_bottom=ci_bottom_dict[model_eval.POFD_BY_THRESHOLD_KEY],
        y_coords_bottom=ci_bottom_dict[model_eval.POD_BY_THRESHOLD_KEY],
        x_coords_top=ci_top_dict[model_eval.POFD_BY_THRESHOLD_KEY],
        y_coords_top=ci_top_dict[model_eval.POD_BY_THRESHOLD_KEY])

    if polygon_object is None:
        return line_handle

    polygon_colour = matplotlib.colors.to_rgba(
        plotting_utils.colour_from_numpy_to_tuple(line_colour),
        POLYGON_OPACITY)

    polygon_patch = PolygonPatch(polygon_object,
                                 lw=0,
                                 ec=polygon_colour,
                                 fc=polygon_colour)

    axes_object.add_patch(polygon_patch)

    return line_handle
Example #11
0
def plot_bootstrapped_reliability_curve(axes_object, ci_bottom_dict,
                                        ci_mean_dict, ci_top_dict):
    """Bootstrapped version of plot_reliability_curve.

    B = number of bins (separated by forecast probability)

    :param axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    :param ci_bottom_dict: Dictionary with the following keys,
        representing the bottom of the confidence interval.
    ci_bottom_dict['mean_forecast_by_bin']: length-B numpy array of mean
        forecast probabilities.
    ci_bottom_dict['event_frequency_by_bin']: length-B numpy array of
        conditional event frequencies.

    :param ci_mean_dict: Same but for mean of confidence interval.
    :param ci_top_dict: Same but for top of confidence interval.
    """

    plot_reliability_curve(
        axes_object=axes_object,
        mean_forecast_by_bin=ci_mean_dict[model_eval.MEAN_FORECAST_BY_BIN_KEY],
        event_frequency_by_bin=ci_mean_dict[model_eval.EVENT_FREQ_BY_BIN_KEY])

    polygon_object = _confidence_interval_to_polygon(
        x_coords_bottom=ci_bottom_dict[model_eval.MEAN_FORECAST_BY_BIN_KEY],
        y_coords_bottom=ci_bottom_dict[model_eval.EVENT_FREQ_BY_BIN_KEY],
        x_coords_top=ci_top_dict[model_eval.MEAN_FORECAST_BY_BIN_KEY],
        y_coords_top=ci_top_dict[model_eval.EVENT_FREQ_BY_BIN_KEY])

    if polygon_object is None:
        return

    polygon_colour = matplotlib.colors.to_rgba(
        plotting_utils.colour_from_numpy_to_tuple(RELIABILITY_COLOUR),
        POLYGON_OPACITY)

    polygon_patch = PolygonPatch(polygon_object,
                                 lw=0,
                                 ec=polygon_colour,
                                 fc=polygon_colour)

    axes_object.add_patch(polygon_patch)
Example #12
0
def plot_bootstrapped_attributes_diagram(figure_object, axes_object,
                                         ci_bottom_dict, ci_mean_dict,
                                         ci_top_dict, num_examples_by_bin):
    """Bootstrapped version of plot_attributes_diagram.

    :param figure_object: Instance of `matplotlib.figure.Figure`.
    :param axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    :param ci_bottom_dict: See doc for `plot_bootstrapped_reliability_curve`.
    :param ci_mean_dict: Same.
    :param ci_top_dict: Same.
    :param num_examples_by_bin: See doc for `plot_attributes_diagram`.
    """

    plot_attributes_diagram(
        figure_object=figure_object,
        axes_object=axes_object,
        mean_forecast_by_bin=ci_mean_dict[model_eval.MEAN_FORECAST_BY_BIN_KEY],
        event_frequency_by_bin=ci_mean_dict[model_eval.EVENT_FREQ_BY_BIN_KEY],
        num_examples_by_bin=num_examples_by_bin)

    polygon_object = _confidence_interval_to_polygon(
        x_coords_bottom=ci_bottom_dict[model_eval.MEAN_FORECAST_BY_BIN_KEY],
        y_coords_bottom=ci_bottom_dict[model_eval.EVENT_FREQ_BY_BIN_KEY],
        x_coords_top=ci_top_dict[model_eval.MEAN_FORECAST_BY_BIN_KEY],
        y_coords_top=ci_top_dict[model_eval.EVENT_FREQ_BY_BIN_KEY])

    if polygon_object is None:
        return

    polygon_colour = matplotlib.colors.to_rgba(
        plotting_utils.colour_from_numpy_to_tuple(RELIABILITY_COLOUR),
        POLYGON_OPACITY)

    polygon_patch = PolygonPatch(polygon_object,
                                 lw=0,
                                 ec=polygon_colour,
                                 fc=polygon_colour)

    axes_object.add_patch(polygon_patch)
Example #13
0
def _label_bars(axes_object, y_coords, y_strings):
    """Labels bars in graph.

    J = number of bars

    :param axes_object: Will plot on these axes (instance of
        `matplotlib.axes._subplots.AxesSubplot`).
    :param y_coords: length-J numpy array with y-coordinates of bars.
    :param y_strings: length-J list of labels.
    """

    x_min, x_max = pyplot.xlim()
    x_coord_for_text = x_min + 0.025 * (x_max - x_min)

    this_colour = plotting_utils.colour_from_numpy_to_tuple(TEXT_COLOUR)

    for j in range(len(y_coords)):
        axes_object.text(x_coord_for_text,
                         y_coords[j],
                         '   ' + y_strings[j],
                         color=this_colour,
                         horizontalalignment='left',
                         verticalalignment='center',
                         fontsize=LABEL_FONT_SIZE)
Example #14
0
def plot_reliability_curve(
        axes_object,
        mean_forecast_by_bin,
        event_frequency_by_bin,
        line_colour=DEFAULT_RELIABILITY_COLOUR,
        line_width=DEFAULT_RELIABILITY_WIDTH,
        perfect_line_colour=DEFAULT_PERFECT_RELIABILITY_COLOUR,
        perfect_line_width=DEFAULT_PERFECT_RELIABILITY_WIDTH):
    """Plots reliability curve.

    B = number of bins (separated by forecast probability)

    :param axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    :param mean_forecast_by_bin: length-B numpy array of mean forecast
        probabilities.
    :param event_frequency_by_bin: length-B numpy array of mean observed
        labels (conditional event frequencies).
    :param line_colour: Colour (in any format accepted by `matplotlib.colors`).
    :param line_width: Line width (real positive number).
    :param perfect_line_colour: Colour of reference line (reliability curve with
        reliability = 0).
    :param perfect_line_width: Width of reference line.
    """

    error_checking.assert_is_numpy_array(mean_forecast_by_bin,
                                         num_dimensions=1)
    error_checking.assert_is_geq_numpy_array(mean_forecast_by_bin,
                                             0.,
                                             allow_nan=True)
    error_checking.assert_is_leq_numpy_array(mean_forecast_by_bin,
                                             1.,
                                             allow_nan=True)
    num_bins = len(mean_forecast_by_bin)

    error_checking.assert_is_numpy_array(event_frequency_by_bin,
                                         exact_dimensions=numpy.array(
                                             [num_bins]))
    error_checking.assert_is_geq_numpy_array(event_frequency_by_bin,
                                             0.,
                                             allow_nan=True)
    error_checking.assert_is_leq_numpy_array(event_frequency_by_bin,
                                             1.,
                                             allow_nan=True)

    perfect_x_coords, perfect_y_coords = (
        model_eval.get_perfect_reliability_curve())

    axes_object.plot(
        perfect_x_coords,
        perfect_y_coords,
        color=plotting_utils.colour_from_numpy_to_tuple(perfect_line_colour),
        linestyle='dashed',
        linewidth=perfect_line_width)

    nan_flags = numpy.logical_or(numpy.isnan(mean_forecast_by_bin),
                                 numpy.isnan(event_frequency_by_bin))

    if not numpy.all(nan_flags):
        real_indices = numpy.where(numpy.invert(nan_flags))[0]

        axes_object.plot(
            mean_forecast_by_bin[real_indices],
            event_frequency_by_bin[real_indices],
            color=plotting_utils.colour_from_numpy_to_tuple(line_colour),
            linestyle='solid',
            linewidth=line_width)

    axes_object.set_xlabel('Forecast probability')
    axes_object.set_ylabel('Conditional event frequency')
    axes_object.set_xlim(0., 1.)
    axes_object.set_ylim(0., 1.)
Example #15
0
def plot_2d_grid_with_pm_signs(saliency_matrix_2d,
                               axes_object,
                               colour_map_object,
                               max_absolute_colour_value,
                               min_font_size=DEFAULT_MIN_FONT_SIZE,
                               max_font_size=DEFAULT_MAX_FONT_SIZE):
    """Plots 2-D saliency map with plus and minus signs ("+" and "-").

    M = number of rows in spatial grid
    N = number of columns in spatial grid

    :param saliency_matrix_2d: See doc for `plot_2d_grid_with_contours`.
    :param axes_object: Same.
    :param colour_map_object: Same.
    :param max_absolute_colour_value: Same.
    :param min_font_size: Minimum font size (used for zero saliency).
    :param max_font_size: Max font size (used for max absolute value).
    """

    error_checking.assert_is_geq(max_absolute_colour_value, 0.)
    max_absolute_colour_value = max([max_absolute_colour_value, 0.001])

    error_checking.assert_is_numpy_array_without_nan(saliency_matrix_2d)
    error_checking.assert_is_numpy_array(saliency_matrix_2d, num_dimensions=2)

    rgb_matrix, font_size_matrix = _saliency_to_colour_and_size(
        saliency_matrix=saliency_matrix_2d,
        colour_map_object=colour_map_object,
        max_absolute_colour_value=max_absolute_colour_value,
        min_font_size=min_font_size,
        max_font_size=max_font_size)

    num_grid_rows = saliency_matrix_2d.shape[0]
    num_grid_columns = saliency_matrix_2d.shape[1]
    x_coord_spacing = num_grid_columns**-1
    y_coord_spacing = num_grid_rows**-1

    x_coords, y_coords = grids.get_xy_grid_points(
        x_min_metres=x_coord_spacing / 2,
        y_min_metres=y_coord_spacing / 2,
        x_spacing_metres=x_coord_spacing,
        y_spacing_metres=y_coord_spacing,
        num_rows=num_grid_rows,
        num_columns=num_grid_columns)

    for i in range(num_grid_rows):
        for j in range(num_grid_columns):
            this_colour_tuple = plotting_utils.colour_from_numpy_to_tuple(
                rgb_matrix[i, j, ...])

            if saliency_matrix_2d[i, j] >= 0:
                axes_object.text(x_coords[i],
                                 y_coords[j],
                                 '+',
                                 fontsize=font_size_matrix[i, j],
                                 color=this_colour_tuple,
                                 horizontalalignment='center',
                                 verticalalignment='center',
                                 transform=axes_object.transAxes)
            else:
                axes_object.text(x_coords[i],
                                 y_coords[j],
                                 '_',
                                 fontsize=font_size_matrix[i, j],
                                 color=this_colour_tuple,
                                 horizontalalignment='center',
                                 verticalalignment='bottom',
                                 transform=axes_object.transAxes)
Example #16
0
def plot_performance_diagram(axes_object,
                             pod_by_threshold,
                             success_ratio_by_threshold,
                             line_colour=DEFAULT_PERFORMANCE_COLOUR,
                             line_width=DEFAULT_PERFORMANCE_WIDTH,
                             bias_line_colour=DEFAULT_FREQ_BIAS_COLOUR,
                             bias_line_width=DEFAULT_FREQ_BIAS_WIDTH):
    """Plots performance diagram.

    T = number of binarization thresholds

    For the definition of a "binarization threshold" and the role they play in
    performance diagrams, see
    `model_evaluation.get_points_in_performance_diagram`.

    :param axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    :param pod_by_threshold: length-T numpy array of POD (probability of
        detection) values.
    :param success_ratio_by_threshold: length-T numpy array of success ratios.
    :param line_colour: Colour (in any format accepted by `matplotlib.colors`).
    :param line_width: Line width (real positive number).
    :param bias_line_colour: Colour of contour lines for frequency bias.
    :param bias_line_width: Width of contour lines for frequency bias.
    """

    error_checking.assert_is_numpy_array(pod_by_threshold, num_dimensions=1)
    error_checking.assert_is_geq_numpy_array(pod_by_threshold,
                                             0.,
                                             allow_nan=True)
    error_checking.assert_is_leq_numpy_array(pod_by_threshold,
                                             1.,
                                             allow_nan=True)
    num_thresholds = len(pod_by_threshold)

    error_checking.assert_is_numpy_array(success_ratio_by_threshold,
                                         exact_dimensions=numpy.array(
                                             [num_thresholds]))
    error_checking.assert_is_geq_numpy_array(success_ratio_by_threshold,
                                             0.,
                                             allow_nan=True)
    error_checking.assert_is_leq_numpy_array(success_ratio_by_threshold,
                                             1.,
                                             allow_nan=True)

    success_ratio_matrix, pod_matrix = model_eval.get_sr_pod_grid()
    csi_matrix = model_eval.csi_from_sr_and_pod(success_ratio_matrix,
                                                pod_matrix)
    frequency_bias_matrix = model_eval.frequency_bias_from_sr_and_pod(
        success_ratio_matrix, pod_matrix)

    this_colour_map_object, this_colour_norm_object = _get_csi_colour_scheme()

    pyplot.contourf(success_ratio_matrix,
                    pod_matrix,
                    csi_matrix,
                    LEVELS_FOR_CSI_CONTOURS,
                    cmap=this_colour_map_object,
                    norm=this_colour_norm_object,
                    vmin=0.,
                    vmax=1.,
                    axes=axes_object)

    colour_bar_object = plotting_utils.plot_colour_bar(
        axes_object_or_matrix=axes_object,
        data_matrix=csi_matrix,
        colour_map_object=this_colour_map_object,
        colour_norm_object=this_colour_norm_object,
        orientation_string='vertical',
        extend_min=False,
        extend_max=False)

    colour_bar_object.set_label('CSI (critical success index)')

    bias_colour_tuple = plotting_utils.colour_from_numpy_to_tuple(
        bias_line_colour)

    bias_colours_2d_tuple = ()
    for _ in range(len(LEVELS_FOR_FREQ_BIAS_CONTOURS)):
        bias_colours_2d_tuple += (bias_colour_tuple, )

    bias_contour_object = pyplot.contour(success_ratio_matrix,
                                         pod_matrix,
                                         frequency_bias_matrix,
                                         LEVELS_FOR_FREQ_BIAS_CONTOURS,
                                         colors=bias_colours_2d_tuple,
                                         linewidths=bias_line_width,
                                         linestyles='dashed',
                                         axes=axes_object)

    pyplot.clabel(bias_contour_object,
                  inline=True,
                  inline_spacing=PIXEL_PADDING_FOR_FREQ_BIAS_LABELS,
                  fmt=STRING_FORMAT_FOR_FREQ_BIAS_LABELS,
                  fontsize=FONT_SIZE)

    nan_flags = numpy.logical_or(numpy.isnan(success_ratio_by_threshold),
                                 numpy.isnan(pod_by_threshold))

    if not numpy.all(nan_flags):
        real_indices = numpy.where(numpy.invert(nan_flags))[0]

        axes_object.plot(
            success_ratio_by_threshold[real_indices],
            pod_by_threshold[real_indices],
            color=plotting_utils.colour_from_numpy_to_tuple(line_colour),
            linestyle='solid',
            linewidth=line_width)

    axes_object.set_xlabel('Success ratio (1 - FAR)')
    axes_object.set_ylabel('POD (probability of detection)')
    axes_object.set_xlim(0., 1.)
    axes_object.set_ylim(0., 1.)
Example #17
0
def plot_reliability_curve(axes_object, mean_forecast_by_bin,
                           event_frequency_by_bin):
    """Plots reliability curve.

    B = number of bins (separated by forecast probability)

    :param axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    :param mean_forecast_by_bin: length-B numpy array of mean forecast
        probabilities.
    :param event_frequency_by_bin: length-B numpy array of mean observed
        labels (conditional event frequencies).
    """

    error_checking.assert_is_numpy_array(mean_forecast_by_bin,
                                         num_dimensions=1)
    error_checking.assert_is_geq_numpy_array(mean_forecast_by_bin,
                                             0.,
                                             allow_nan=True)
    error_checking.assert_is_leq_numpy_array(mean_forecast_by_bin,
                                             1.,
                                             allow_nan=True)

    num_bins = len(mean_forecast_by_bin)
    expected_dim = numpy.array([num_bins], dtype=int)

    error_checking.assert_is_numpy_array(event_frequency_by_bin,
                                         exact_dimensions=expected_dim)
    error_checking.assert_is_geq_numpy_array(event_frequency_by_bin,
                                             0.,
                                             allow_nan=True)
    error_checking.assert_is_leq_numpy_array(event_frequency_by_bin,
                                             1.,
                                             allow_nan=True)

    perfect_x_coords, perfect_y_coords = (
        model_eval.get_perfect_reliability_curve())

    axes_object.plot(
        perfect_x_coords,
        perfect_y_coords,
        color=plotting_utils.colour_from_numpy_to_tuple(PERFECT_RELIA_COLOUR),
        linestyle='dashed',
        linewidth=PERFECT_RELIA_WIDTH)

    nan_flags = numpy.logical_or(numpy.isnan(mean_forecast_by_bin),
                                 numpy.isnan(event_frequency_by_bin))

    if not numpy.all(nan_flags):
        real_indices = numpy.where(numpy.invert(nan_flags))[0]

        axes_object.plot(mean_forecast_by_bin[real_indices],
                         event_frequency_by_bin[real_indices],
                         color=plotting_utils.colour_from_numpy_to_tuple(
                             RELIABILITY_COLOUR),
                         linestyle='solid',
                         linewidth=RELIABILITY_WIDTH)

    axes_object.set_xlabel('Forecast probability')
    axes_object.set_ylabel('Conditional event frequency')
    axes_object.set_xlim(0., 1.)
    axes_object.set_ylim(0., 1.)
Example #18
0
def plot_roc_curve(axes_object,
                   pod_by_threshold,
                   pofd_by_threshold,
                   line_colour=DEFAULT_ROC_COLOUR,
                   line_width=DEFAULT_ROC_WIDTH,
                   random_line_colour=DEFAULT_RANDOM_ROC_COLOUR,
                   random_line_width=DEFAULT_RANDOM_ROC_WIDTH):
    """Plots ROC (receiver operating characteristic) curve.

    T = number of binarization thresholds

    For the definition of a "binarization threshold" and the role they play in
    ROC curves, see `model_evaluation.get_points_in_roc_curve`.

    :param axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    :param pod_by_threshold: length-T numpy array of POD (probability of
        detection) values.
    :param pofd_by_threshold: length-T numpy array of POFD (probability of false
        detection) values.
    :param line_colour: Colour (in any format accepted by `matplotlib.colors`).
    :param line_width: Line width (real positive number).
    :param random_line_colour: Colour of reference line (ROC curve for a random
        predictor).
    :param random_line_width: Width of reference line.
    """

    error_checking.assert_is_numpy_array(pod_by_threshold, num_dimensions=1)
    error_checking.assert_is_geq_numpy_array(pod_by_threshold,
                                             0.,
                                             allow_nan=True)
    error_checking.assert_is_leq_numpy_array(pod_by_threshold,
                                             1.,
                                             allow_nan=True)
    num_thresholds = len(pod_by_threshold)

    error_checking.assert_is_numpy_array(pofd_by_threshold,
                                         exact_dimensions=numpy.array(
                                             [num_thresholds]))
    error_checking.assert_is_geq_numpy_array(pofd_by_threshold,
                                             0.,
                                             allow_nan=True)
    error_checking.assert_is_leq_numpy_array(pofd_by_threshold,
                                             1.,
                                             allow_nan=True)

    pofd_matrix, pod_matrix = model_eval.get_pofd_pod_grid()
    peirce_score_matrix = pod_matrix - pofd_matrix

    this_colour_map_object, this_colour_norm_object = _get_peirce_colour_scheme(
    )

    pyplot.contourf(pofd_matrix,
                    pod_matrix,
                    peirce_score_matrix,
                    LEVELS_FOR_CSI_CONTOURS,
                    cmap=this_colour_map_object,
                    norm=this_colour_norm_object,
                    vmin=0.,
                    vmax=1.,
                    axes=axes_object)

    colour_bar_object = plotting_utils.plot_colour_bar(
        axes_object_or_matrix=axes_object,
        data_matrix=peirce_score_matrix,
        colour_map_object=this_colour_map_object,
        colour_norm_object=this_colour_norm_object,
        orientation_string='vertical',
        extend_min=False,
        extend_max=False)

    colour_bar_object.set_label('Peirce score (POD minus POFD)')

    random_x_coords, random_y_coords = model_eval.get_random_roc_curve()
    axes_object.plot(
        random_x_coords,
        random_y_coords,
        color=plotting_utils.colour_from_numpy_to_tuple(random_line_colour),
        linestyle='dashed',
        linewidth=random_line_width)

    nan_flags = numpy.logical_or(numpy.isnan(pofd_by_threshold),
                                 numpy.isnan(pod_by_threshold))

    if not numpy.all(nan_flags):
        real_indices = numpy.where(numpy.invert(nan_flags))[0]

        axes_object.plot(
            pofd_by_threshold[real_indices],
            pod_by_threshold[real_indices],
            color=plotting_utils.colour_from_numpy_to_tuple(line_colour),
            linestyle='solid',
            linewidth=line_width)

    axes_object.set_xlabel('POFD (probability of false detection)')
    axes_object.set_ylabel('POD (probability of detection)')
    axes_object.set_xlim(0., 1.)
    axes_object.set_ylim(0., 1.)
Example #19
0
def plot_bootstrapped_attributes_diagram(
        figure_object,
        axes_object,
        ci_bottom_dict,
        ci_mean_dict,
        ci_top_dict,
        num_examples_by_bin,
        reliability_line_colour=DEFAULT_RELIABILITY_COLOUR,
        reliability_line_width=DEFAULT_RELIABILITY_WIDTH,
        perfect_relia_line_colour=DEFAULT_PERFECT_RELIABILITY_COLOUR,
        perfect_relia_line_width=DEFAULT_PERFECT_RELIABILITY_WIDTH,
        no_skill_line_colour=DEFAULT_ZERO_BSS_COLOUR,
        no_skill_line_width=DEFAULT_ZERO_BSS_WIDTH,
        other_line_colour=DEFAULT_CLIMATOLOGY_COLOUR,
        other_line_width=DEFAULT_CLIMATOLOGY_WIDTH,
        histogram_bar_face_colour=DEFAULT_HISTOGRAM_FACE_COLOUR,
        histogram_bar_edge_colour=DEFAULT_HISTOGRAM_EDGE_COLOUR,
        histogram_bar_edge_width=DEFAULT_HISTOGRAM_EDGE_WIDTH):
    """Bootstrapped version of plot_attributes_diagram.

    :param figure_object: Instance of `matplotlib.figure.Figure`.
    :param axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    :param ci_bottom_dict: See doc for `plot_bootstrapped_reliability_curve`.
    :param ci_mean_dict: Same.
    :param ci_top_dict: Same.
    :param num_examples_by_bin: See doc for `plot_attributes_diagram`.
    :param reliability_line_colour: Same.
    :param reliability_line_width: Same.
    :param perfect_relia_line_colour: Same.
    :param perfect_relia_line_width: Same.
    :param no_skill_line_colour: Same.
    :param no_skill_line_width: Same.
    :param other_line_colour: Same.
    :param other_line_width: Same.
    :param histogram_bar_face_colour: Same.
    :param histogram_bar_edge_colour: Same.
    :param histogram_bar_edge_width: Same.
    """

    plot_attributes_diagram(
        figure_object=figure_object,
        axes_object=axes_object,
        mean_forecast_by_bin=ci_mean_dict[model_eval.MEAN_FORECAST_BY_BIN_KEY],
        event_frequency_by_bin=ci_mean_dict[model_eval.EVENT_FREQ_BY_BIN_KEY],
        num_examples_by_bin=num_examples_by_bin,
        reliability_line_colour=reliability_line_colour,
        reliability_line_width=reliability_line_width,
        perfect_relia_line_colour=perfect_relia_line_colour,
        perfect_relia_line_width=perfect_relia_line_width,
        no_skill_line_colour=no_skill_line_colour,
        no_skill_line_width=no_skill_line_width,
        other_line_colour=other_line_colour,
        other_line_width=other_line_width,
        histogram_bar_face_colour=histogram_bar_face_colour,
        histogram_bar_edge_colour=histogram_bar_edge_colour,
        histogram_bar_edge_width=histogram_bar_edge_width)

    polygon_object = _confidence_interval_to_polygon(
        x_coords_bottom=ci_bottom_dict[model_eval.MEAN_FORECAST_BY_BIN_KEY],
        y_coords_bottom=ci_bottom_dict[model_eval.EVENT_FREQ_BY_BIN_KEY],
        x_coords_top=ci_top_dict[model_eval.MEAN_FORECAST_BY_BIN_KEY],
        y_coords_top=ci_top_dict[model_eval.EVENT_FREQ_BY_BIN_KEY])

    polygon_colour = matplotlib.colors.to_rgba(
        plotting_utils.colour_from_numpy_to_tuple(reliability_line_colour),
        TRANSPARENCY_FOR_CONFIDENCE_INTERVAL)

    polygon_patch = PolygonPatch(polygon_object,
                                 lw=0,
                                 ec=polygon_colour,
                                 fc=polygon_colour)

    axes_object.add_patch(polygon_patch)
Example #20
0
def _plot_background_of_attributes_diagram(axes_object, climatology):
    """Plots background (references lines and polygons) of attributes diagram.

    For more on the attributes diagram, see Hsu and Murphy (1986).

    BSS = Brier skill score.  For more on the BSS, see
    `model_evaluation.get_brier_skill_score`.

    :param axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    :param climatology: Event frequency for the entire dataset.
    """

    error_checking.assert_is_geq(climatology, 0.)
    error_checking.assert_is_leq(climatology, 1.)

    (x_coords_left_skill_area, y_coords_left_skill_area,
     x_coords_right_skill_area, y_coords_right_skill_area
     ) = model_eval.get_skill_areas_in_reliability_curve(climatology)

    skill_area_colour = matplotlib.colors.to_rgba(
        plotting_utils.colour_from_numpy_to_tuple(ZERO_BSS_COLOUR),
        POSITIVE_BSS_OPACITY)

    left_polygon_object = polygons.vertex_arrays_to_polygon_object(
        x_coords_left_skill_area, y_coords_left_skill_area)
    left_polygon_patch = PolygonPatch(left_polygon_object,
                                      lw=0,
                                      ec=skill_area_colour,
                                      fc=skill_area_colour)

    axes_object.add_patch(left_polygon_patch)

    right_polygon_object = polygons.vertex_arrays_to_polygon_object(
        x_coords_right_skill_area, y_coords_right_skill_area)
    right_polygon_patch = PolygonPatch(right_polygon_object,
                                       lw=0,
                                       ec=skill_area_colour,
                                       fc=skill_area_colour)

    axes_object.add_patch(right_polygon_patch)

    no_skill_x_coords, no_skill_y_coords = (
        model_eval.get_no_skill_reliability_curve(climatology))

    axes_object.plot(
        no_skill_x_coords,
        no_skill_y_coords,
        color=plotting_utils.colour_from_numpy_to_tuple(ZERO_BSS_COLOUR),
        linestyle='solid',
        linewidth=ZERO_BSS_LINE_WIDTH)

    climo_x_coords, climo_y_coords = (
        model_eval.get_climatology_line_for_reliability_curve(climatology))

    axes_object.plot(
        climo_x_coords,
        climo_y_coords,
        color=plotting_utils.colour_from_numpy_to_tuple(CLIMO_COLOUR),
        linestyle='dashed',
        linewidth=CLIMO_LINE_WIDTH)

    no_resolution_x_coords, no_resolution_y_coords = (
        model_eval.get_no_resolution_line_for_reliability_curve(climatology))

    axes_object.plot(
        no_resolution_x_coords,
        no_resolution_y_coords,
        color=plotting_utils.colour_from_numpy_to_tuple(CLIMO_COLOUR),
        linestyle='dashed',
        linewidth=CLIMO_LINE_WIDTH)
Example #21
0
def _plot_background_of_attributes_diagram(
        axes_object,
        climatology,
        no_skill_line_colour=DEFAULT_ZERO_BSS_COLOUR,
        no_skill_line_width=DEFAULT_ZERO_BSS_WIDTH,
        other_line_colour=DEFAULT_CLIMATOLOGY_COLOUR,
        other_line_width=DEFAULT_CLIMATOLOGY_WIDTH):
    """Plots background (references lines and polygons) of attributes diagram.

    For more on the attributes diagram, see Hsu and Murphy (1986).

    BSS = Brier skill score.  For more on the BSS, see
    `model_evaluation.get_brier_skill_score`.

    :param axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    :param climatology: Event frequency for the entire dataset.
    :param no_skill_line_colour: Colour (in any format accepted by
        `matplotlib.colors`) of no-skill line, where BSS = 0.
    :param no_skill_line_width: Width (real positive number) of no-skill line.
    :param other_line_colour: Colour of climatology and no-resolution lines.
    :param other_line_width: Width of climatology and no-resolution lines.
    """

    error_checking.assert_is_geq(climatology, 0.)
    error_checking.assert_is_leq(climatology, 1.)

    (x_vertices_for_left_skill_area, y_vertices_for_left_skill_area,
     x_vertices_for_right_skill_area, y_vertices_for_right_skill_area
     ) = model_eval.get_skill_areas_in_reliability_curve(climatology)

    skill_area_colour = matplotlib.colors.to_rgba(
        plotting_utils.colour_from_numpy_to_tuple(no_skill_line_colour),
        TRANSPARENCY_FOR_POSITIVE_BSS_AREA)

    left_polygon_object = polygons.vertex_arrays_to_polygon_object(
        x_vertices_for_left_skill_area, y_vertices_for_left_skill_area)
    left_polygon_patch = PolygonPatch(left_polygon_object,
                                      lw=0,
                                      ec=skill_area_colour,
                                      fc=skill_area_colour)

    axes_object.add_patch(left_polygon_patch)

    right_polygon_object = polygons.vertex_arrays_to_polygon_object(
        x_vertices_for_right_skill_area, y_vertices_for_right_skill_area)
    right_polygon_patch = PolygonPatch(right_polygon_object,
                                       lw=0,
                                       ec=skill_area_colour,
                                       fc=skill_area_colour)

    axes_object.add_patch(right_polygon_patch)

    no_skill_x_coords, no_skill_y_coords = (
        model_eval.get_no_skill_reliability_curve(climatology))

    axes_object.plot(
        no_skill_x_coords,
        no_skill_y_coords,
        color=plotting_utils.colour_from_numpy_to_tuple(no_skill_line_colour),
        linestyle='solid',
        linewidth=no_skill_line_width)

    climo_x_coords, climo_y_coords = (
        model_eval.get_climatology_line_for_reliability_curve(climatology))

    axes_object.plot(
        climo_x_coords,
        climo_y_coords,
        color=plotting_utils.colour_from_numpy_to_tuple(other_line_colour),
        linestyle='dashed',
        linewidth=other_line_width)

    no_resolution_x_coords, no_resolution_y_coords = (
        model_eval.get_no_resolution_line_for_reliability_curve(climatology))

    axes_object.plot(
        no_resolution_x_coords,
        no_resolution_y_coords,
        color=plotting_utils.colour_from_numpy_to_tuple(other_line_colour),
        linestyle='dashed',
        linewidth=other_line_width)
Example #22
0
def plot_performance_diagram(axes_object,
                             pod_by_threshold,
                             success_ratio_by_threshold,
                             line_colour=PERF_DIAGRAM_COLOUR,
                             plot_background=True):
    """Plots performance diagram.

    T = number of binarization thresholds

    For the definition of a "binarization threshold" and the role they play in
    performance diagrams, see
    `model_evaluation.get_points_in_performance_diagram`.

    :param axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    :param pod_by_threshold: length-T numpy array of POD (probability of
        detection) values.
    :param success_ratio_by_threshold: length-T numpy array of success ratios.
    :param line_colour: Line colour.
    :param plot_background: Boolean flag.  If True, will plot background
        (frequency-bias and CSI contours).
    :return: line_handle: Line handle for ROC curve.
    """

    error_checking.assert_is_numpy_array(pod_by_threshold, num_dimensions=1)
    error_checking.assert_is_geq_numpy_array(pod_by_threshold,
                                             0.,
                                             allow_nan=True)
    error_checking.assert_is_leq_numpy_array(pod_by_threshold,
                                             1.,
                                             allow_nan=True)

    num_thresholds = len(pod_by_threshold)
    expected_dim = numpy.array([num_thresholds], dtype=int)

    error_checking.assert_is_numpy_array(success_ratio_by_threshold,
                                         exact_dimensions=expected_dim)
    error_checking.assert_is_geq_numpy_array(success_ratio_by_threshold,
                                             0.,
                                             allow_nan=True)
    error_checking.assert_is_leq_numpy_array(success_ratio_by_threshold,
                                             1.,
                                             allow_nan=True)

    error_checking.assert_is_boolean(plot_background)

    if plot_background:
        success_ratio_matrix, pod_matrix = model_eval.get_sr_pod_grid()
        csi_matrix = model_eval.csi_from_sr_and_pod(
            success_ratio_array=success_ratio_matrix, pod_array=pod_matrix)
        frequency_bias_matrix = model_eval.frequency_bias_from_sr_and_pod(
            success_ratio_array=success_ratio_matrix, pod_array=pod_matrix)

        this_colour_map_object, this_colour_norm_object = (
            _get_csi_colour_scheme())

        pyplot.contourf(success_ratio_matrix,
                        pod_matrix,
                        csi_matrix,
                        CSI_LEVELS,
                        cmap=this_colour_map_object,
                        norm=this_colour_norm_object,
                        vmin=0.,
                        vmax=1.,
                        axes=axes_object)

        colour_bar_object = plotting_utils.plot_colour_bar(
            axes_object_or_matrix=axes_object,
            data_matrix=csi_matrix,
            colour_map_object=this_colour_map_object,
            colour_norm_object=this_colour_norm_object,
            orientation_string='vertical',
            extend_min=False,
            extend_max=False,
            fraction_of_axis_length=0.8)

        colour_bar_object.set_label('CSI (critical success index)')

        bias_colour_tuple = plotting_utils.colour_from_numpy_to_tuple(
            FREQ_BIAS_COLOUR)

        bias_colours_2d_tuple = ()
        for _ in range(len(FREQ_BIAS_LEVELS)):
            bias_colours_2d_tuple += (bias_colour_tuple, )

        bias_contour_object = pyplot.contour(success_ratio_matrix,
                                             pod_matrix,
                                             frequency_bias_matrix,
                                             FREQ_BIAS_LEVELS,
                                             colors=bias_colours_2d_tuple,
                                             linewidths=FREQ_BIAS_WIDTH,
                                             linestyles='dashed',
                                             axes=axes_object)

        pyplot.clabel(bias_contour_object,
                      inline=True,
                      inline_spacing=FREQ_BIAS_PADDING,
                      fmt=FREQ_BIAS_STRING_FORMAT,
                      fontsize=FONT_SIZE)

    nan_flags = numpy.logical_or(numpy.isnan(success_ratio_by_threshold),
                                 numpy.isnan(pod_by_threshold))

    if numpy.all(nan_flags):
        line_handle = None
    else:
        real_indices = numpy.where(numpy.invert(nan_flags))[0]

        line_handle = axes_object.plot(
            success_ratio_by_threshold[real_indices],
            pod_by_threshold[real_indices],
            color=plotting_utils.colour_from_numpy_to_tuple(line_colour),
            linestyle='solid',
            linewidth=PERF_DIAGRAM_WIDTH)[0]

    axes_object.set_xlabel('Success ratio (1 - FAR)')
    axes_object.set_ylabel('POD (probability of detection)')
    axes_object.set_xlim(0., 1.)
    axes_object.set_ylim(0., 1.)

    return line_handle
Example #23
0
def plot_storm_ids(
        storm_object_table, axes_object, basemap_object,
        plot_near_centroids=False, include_secondary_ids=False,
        font_colour=DEFAULT_FONT_COLOUR, font_size=DEFAULT_FONT_SIZE):
    """Plots storm IDs as text.

    :param storm_object_table: See doc for `plot_storm_outlines`.
    :param axes_object: Same.
    :param basemap_object: Same.
    :param plot_near_centroids: Boolean flag.  If True, will plot each ID near
        the storm centroid.  If False, will plot each ID near southeasternmost
        point in storm outline.
    :param include_secondary_ids: Boolean flag.  If True, will plot full IDs
        (primary_secondary).  If False, will plot only primary IDs.
    :param font_colour: Font colour.
    :param font_size: Font size.
    """

    error_checking.assert_is_boolean(plot_near_centroids)
    error_checking.assert_is_boolean(include_secondary_ids)

    font_colour_tuple = plotting_utils.colour_from_numpy_to_tuple(font_colour)
    num_storm_objects = len(storm_object_table.index)

    if plot_near_centroids:
        text_x_coords_metres, text_y_coords_metres = basemap_object(
            storm_object_table[tracking_utils.CENTROID_LONGITUDE_COLUMN].values,
            storm_object_table[tracking_utils.CENTROID_LATITUDE_COLUMN].values
        )
    else:
        text_x_coords_metres = numpy.full(num_storm_objects, numpy.nan)
        text_y_coords_metres = numpy.full(num_storm_objects, numpy.nan)

        for i in range(num_storm_objects):
            this_vertex_dict_latlng = polygons.polygon_object_to_vertex_arrays(
                storm_object_table[
                    tracking_utils.LATLNG_POLYGON_COLUMN].values[i]
            )

            these_x_metres, these_y_metres = basemap_object(
                this_vertex_dict_latlng[polygons.EXTERIOR_X_COLUMN],
                this_vertex_dict_latlng[polygons.EXTERIOR_Y_COLUMN]
            )

            this_index = numpy.argmax(these_x_metres - these_y_metres)
            text_x_coords_metres[i] = these_x_metres[this_index]
            text_y_coords_metres[i] = these_y_metres[this_index]

    for i in range(num_storm_objects):
        this_primary_id_string = storm_object_table[
            tracking_utils.PRIMARY_ID_COLUMN].values[i]

        try:
            this_primary_id_string = this_primary_id_string[-4:]
        except ValueError:
            pass

        if include_secondary_ids:
            this_secondary_id_string = storm_object_table[
                tracking_utils.SECONDARY_ID_COLUMN].values[i]

            try:
                this_secondary_id_string = this_secondary_id_string[-4:]
            except ValueError:
                pass

            this_label_string = '{0:s}_{1:s}'.format(
                this_primary_id_string, this_secondary_id_string)
        else:
            this_label_string = this_primary_id_string

        axes_object.text(
            text_x_coords_metres[i], text_y_coords_metres[i], this_label_string,
            fontsize=font_size, fontweight='bold', color=font_colour_tuple,
            horizontalalignment='left', verticalalignment='top')
Example #24
0
def plot_roc_curve(axes_object,
                   pod_by_threshold,
                   pofd_by_threshold,
                   line_colour=ROC_CURVE_COLOUR,
                   plot_background=True):
    """Plots ROC (receiver operating characteristic) curve.

    T = number of binarization thresholds

    For the definition of a "binarization threshold" and the role they play in
    ROC curves, see `model_evaluation.get_points_in_roc_curve`.

    :param axes_object: Instance of `matplotlib.axes._subplots.AxesSubplot`.
    :param pod_by_threshold: length-T numpy array of POD (probability of
        detection) values.
    :param pofd_by_threshold: length-T numpy array of POFD (probability of false
        detection) values.
    :param line_colour: Line colour.
    :param plot_background: Boolean flag.  If True, will plot background
        (reference line and Peirce-score contours).
    :return: line_handle: Line handle for ROC curve.
    """

    error_checking.assert_is_numpy_array(pod_by_threshold, num_dimensions=1)
    error_checking.assert_is_geq_numpy_array(pod_by_threshold,
                                             0.,
                                             allow_nan=True)
    error_checking.assert_is_leq_numpy_array(pod_by_threshold,
                                             1.,
                                             allow_nan=True)

    num_thresholds = len(pod_by_threshold)
    expected_dim = numpy.array([num_thresholds], dtype=int)

    error_checking.assert_is_numpy_array(pofd_by_threshold,
                                         exact_dimensions=expected_dim)
    error_checking.assert_is_geq_numpy_array(pofd_by_threshold,
                                             0.,
                                             allow_nan=True)
    error_checking.assert_is_leq_numpy_array(pofd_by_threshold,
                                             1.,
                                             allow_nan=True)

    error_checking.assert_is_boolean(plot_background)

    if plot_background:
        pofd_matrix, pod_matrix = model_eval.get_pofd_pod_grid()
        peirce_score_matrix = pod_matrix - pofd_matrix

        this_colour_map_object, this_colour_norm_object = (
            _get_peirce_colour_scheme())

        pyplot.contourf(pofd_matrix,
                        pod_matrix,
                        peirce_score_matrix,
                        CSI_LEVELS,
                        cmap=this_colour_map_object,
                        norm=this_colour_norm_object,
                        vmin=0.,
                        vmax=1.,
                        axes=axes_object)

        colour_bar_object = plotting_utils.plot_colour_bar(
            axes_object_or_matrix=axes_object,
            data_matrix=peirce_score_matrix,
            colour_map_object=this_colour_map_object,
            colour_norm_object=this_colour_norm_object,
            orientation_string='vertical',
            extend_min=False,
            extend_max=False,
            fraction_of_axis_length=0.8)

        colour_bar_object.set_label('Peirce score (POD minus POFD)')

        random_x_coords, random_y_coords = model_eval.get_random_roc_curve()
        axes_object.plot(
            random_x_coords,
            random_y_coords,
            color=plotting_utils.colour_from_numpy_to_tuple(RANDOM_ROC_COLOUR),
            linestyle='dashed',
            linewidth=RANDOM_ROC_WIDTH)

    nan_flags = numpy.logical_or(numpy.isnan(pofd_by_threshold),
                                 numpy.isnan(pod_by_threshold))

    if numpy.all(nan_flags):
        line_handle = None
    else:
        real_indices = numpy.where(numpy.invert(nan_flags))[0]

        line_handle = axes_object.plot(
            pofd_by_threshold[real_indices],
            pod_by_threshold[real_indices],
            color=plotting_utils.colour_from_numpy_to_tuple(line_colour),
            linestyle='solid',
            linewidth=ROC_CURVE_WIDTH)[0]

    axes_object.set_xlabel('POFD (probability of false detection)')
    axes_object.set_ylabel('POD (probability of detection)')
    axes_object.set_xlim(0., 1.)
    axes_object.set_ylim(0., 1.)

    return line_handle
Example #25
0
def _plot_2d_regions(figure_objects,
                     axes_object_matrices,
                     model_metadata_dict,
                     list_of_polygon_objects,
                     output_dir_name,
                     full_storm_id_string=None,
                     storm_time_unix_sec=None):
    """Plots regions of interest for 2-D radar data.

    :param figure_objects: See doc for `_plot_3d_radar_cam`.
    :param axes_object_matrices: Same.
    :param model_metadata_dict: Same.
    :param list_of_polygon_objects: List of polygons (instances of
        `shapely.geometry.Polygon`), demarcating regions of interest.
    :param output_dir_name: See doc for `_plot_3d_radar_cam`.
    :param full_storm_id_string: Same.
    :param storm_time_unix_sec: Same.
    """

    conv_2d3d = model_metadata_dict[cnn.CONV_2D3D_KEY]
    figure_index = 1 if conv_2d3d else 0

    training_option_dict = model_metadata_dict[cnn.TRAINING_OPTION_DICT_KEY]
    num_grid_rows = training_option_dict[trainval_io.NUM_ROWS_KEY]
    num_grid_rows *= 1 + int(conv_2d3d)

    list_of_layer_operation_dicts = model_metadata_dict[
        cnn.LAYER_OPERATIONS_KEY]

    if list_of_layer_operation_dicts is None:
        num_channels = len(training_option_dict[trainval_io.RADAR_FIELDS_KEY])
    else:
        num_channels = len(list_of_layer_operation_dicts)

    for this_polygon_object in list_of_polygon_objects:
        for k in range(num_channels):
            i, j = numpy.unravel_index(
                k, axes_object_matrices[figure_index].shape, order='F')

            these_grid_columns = numpy.array(
                this_polygon_object.exterior.xy[0])
            these_grid_rows = num_grid_rows - numpy.array(
                this_polygon_object.exterior.xy[1])

            axes_object_matrices[figure_index][i, j].plot(
                these_grid_columns,
                these_grid_rows,
                color=plotting_utils.colour_from_numpy_to_tuple(REGION_COLOUR),
                linestyle='solid',
                linewidth=REGION_LINE_WIDTH)

    pmm_flag = full_storm_id_string is None and storm_time_unix_sec is None

    output_file_name = plot_input_examples.metadata_to_file_name(
        output_dir_name=output_dir_name,
        is_sounding=False,
        pmm_flag=pmm_flag,
        full_storm_id_string=full_storm_id_string,
        storm_time_unix_sec=storm_time_unix_sec,
        radar_field_name='shear' if conv_2d3d else None)

    print('Saving figure to: "{0:s}"...'.format(output_file_name))
    figure_objects[figure_index].savefig(output_file_name,
                                         dpi=FIGURE_RESOLUTION_DPI,
                                         pad_inches=0,
                                         bbox_inches='tight')
    pyplot.close(figure_objects[figure_index])
Example #26
0
def plot_saliency_for_sounding(saliency_matrix,
                               sounding_field_names,
                               pressure_levels_mb,
                               colour_map_object,
                               max_absolute_colour_value,
                               min_font_size=DEFAULT_MIN_SOUNDING_FONT_SIZE,
                               max_font_size=DEFAULT_MAX_SOUNDING_FONT_SIZE):
    """Plots saliency for one sounding.

    P = number of pressure levels
    F = number of fields

    :param saliency_matrix: P-by-F numpy array of saliency values.
    :param sounding_field_names: length-F list of field names.
    :param pressure_levels_mb: length-P list of pressure levels (millibars).
    :param colour_map_object: See doc for `plot_2d_grid`.
    :param max_absolute_colour_value: Same.
    :param min_font_size: Same.
    :param max_font_size: Same.
    """

    error_checking.assert_is_geq(max_absolute_colour_value, 0.)
    max_absolute_colour_value = max([max_absolute_colour_value, 0.001])

    error_checking.assert_is_greater_numpy_array(pressure_levels_mb, 0.)
    error_checking.assert_is_numpy_array(pressure_levels_mb, num_dimensions=1)

    error_checking.assert_is_list(sounding_field_names)
    error_checking.assert_is_numpy_array(numpy.array(sounding_field_names),
                                         num_dimensions=1)

    num_pressure_levels = len(pressure_levels_mb)
    num_sounding_fields = len(sounding_field_names)

    error_checking.assert_is_numpy_array_without_nan(saliency_matrix)
    error_checking.assert_is_numpy_array(saliency_matrix,
                                         exact_dimensions=numpy.array([
                                             num_pressure_levels,
                                             num_sounding_fields
                                         ]))

    try:
        u_wind_index = sounding_field_names.index(soundings.U_WIND_NAME)
        v_wind_index = sounding_field_names.index(soundings.V_WIND_NAME)
        plot_wind_barbs = True
    except ValueError:
        plot_wind_barbs = False

    if plot_wind_barbs:
        u_wind_saliency_values = saliency_matrix[:, u_wind_index]
        v_wind_saliency_values = saliency_matrix[:, v_wind_index]
        wind_saliency_magnitudes = numpy.sqrt(u_wind_saliency_values**2 +
                                              v_wind_saliency_values**2)

        colour_norm_object = pyplot.Normalize(vmin=0.,
                                              vmax=max_absolute_colour_value)

        rgb_matrix_for_wind = colour_map_object(
            colour_norm_object(wind_saliency_magnitudes))[..., :-1]

        non_wind_flags = numpy.array(
            [f not in WIND_COMPONENT_NAMES for f in sounding_field_names],
            dtype=bool)

        non_wind_indices = numpy.where(non_wind_flags)[0]
        saliency_matrix = saliency_matrix[:, non_wind_indices]
        sounding_field_names = [
            sounding_field_names[k] for k in non_wind_indices
        ]

        sounding_field_names.append(WIND_NAME)
        num_sounding_fields = len(sounding_field_names)

    rgb_matrix, font_size_matrix = _saliency_to_colour_and_size(
        saliency_matrix=saliency_matrix,
        colour_map_object=colour_map_object,
        max_absolute_colour_value=max_absolute_colour_value,
        min_font_size=min_font_size,
        max_font_size=max_font_size)

    _, axes_object = pyplot.subplots(1,
                                     1,
                                     figsize=(FIGURE_WIDTH_INCHES,
                                              FIGURE_HEIGHT_INCHES))

    axes_object.set_facecolor(
        plotting_utils.colour_from_numpy_to_tuple(
            SOUNDING_SALIENCY_BACKGROUND_COLOUR))

    for k in range(num_sounding_fields):
        if sounding_field_names[k] == WIND_NAME:
            for j in range(num_pressure_levels):
                this_vector = numpy.array(
                    [u_wind_saliency_values[j], v_wind_saliency_values[j]])

                this_vector = (WIND_SALIENCY_MULTIPLIER * this_vector /
                               numpy.linalg.norm(this_vector, ord=2))

                this_colour_tuple = plotting_utils.colour_from_numpy_to_tuple(
                    rgb_matrix_for_wind[j, ...])

                axes_object.barbs(k,
                                  pressure_levels_mb[j],
                                  this_vector[0],
                                  this_vector[1],
                                  length=WIND_BARB_LENGTH,
                                  fill_empty=True,
                                  rounding=False,
                                  sizes={'emptybarb': EMPTY_WIND_BARB_RADIUS},
                                  color=this_colour_tuple)

            continue

        for j in range(num_pressure_levels):
            this_colour_tuple = plotting_utils.colour_from_numpy_to_tuple(
                rgb_matrix[j, k, ...])

            if saliency_matrix[j, k] >= 0:
                axes_object.text(k,
                                 pressure_levels_mb[j],
                                 '+',
                                 fontsize=font_size_matrix[j, k],
                                 color=this_colour_tuple,
                                 horizontalalignment='center',
                                 verticalalignment='center')
            else:
                axes_object.text(k,
                                 pressure_levels_mb[j],
                                 '_',
                                 fontsize=font_size_matrix[j, k],
                                 color=this_colour_tuple,
                                 horizontalalignment='center',
                                 verticalalignment='bottom')

    axes_object.set_xlim(-0.5, num_sounding_fields - 0.5)
    axes_object.set_ylim(100, 1000)
    axes_object.invert_yaxis()
    pyplot.yscale('log')
    pyplot.minorticks_off()

    y_tick_locations = numpy.linspace(100, 1000, num=10, dtype=int)
    y_tick_labels = ['{0:d}'.format(p) for p in y_tick_locations]
    pyplot.yticks(y_tick_locations, y_tick_labels)

    x_tick_locations = numpy.linspace(0,
                                      num_sounding_fields - 1,
                                      num=num_sounding_fields,
                                      dtype=float)
    x_tick_labels = [FIELD_NAME_TO_LATEX_DICT[f] for f in sounding_field_names]
    pyplot.xticks(x_tick_locations, x_tick_labels)

    colour_bar_object = plotting_utils.plot_linear_colour_bar(
        axes_object_or_matrix=axes_object,
        data_matrix=saliency_matrix,
        colour_map_object=colour_map_object,
        min_value=0.,
        max_value=max_absolute_colour_value,
        orientation_string='vertical',
        extend_min=True,
        extend_max=True)

    colour_bar_object.set_label('Saliency (absolute value)')
Example #27
0
def plot_storm_centroids(
        storm_object_table, axes_object, basemap_object,
        colour_map_object='random',
        colour_min_unix_sec=None, colour_max_unix_sec=None,
        constant_colour=DEFAULT_CENTROID_COLOUR,
        marker_type=DEFAULT_CENTROID_MARKER_TYPE,
        marker_size=DEFAULT_CENTROID_MARKER_SIZE):
    """Plots storm centroids.

    :param storm_object_table: See doc for `plot_storm_tracks`.
    :param axes_object: Same.
    :param basemap_object: Same.
    :param colour_map_object: See doc for `_process_colour_args`.
    :param colour_min_unix_sec: Same.
    :param colour_max_unix_sec: Same.
    :param constant_colour: Same.
    :param marker_type: Marker type.
    :param marker_size: Marker size.
    :return: colour_bar_object: Handle for colour bar.  If
        `colour_map_object is None`, this will also be None.
    """

    x_coords_metres, y_coords_metres = basemap_object(
        storm_object_table[tracking_utils.CENTROID_LONGITUDE_COLUMN].values,
        storm_object_table[tracking_utils.CENTROID_LATITUDE_COLUMN].values
    )

    storm_object_table = storm_object_table.assign(**{
        tracking_utils.CENTROID_X_COLUMN: x_coords_metres,
        tracking_utils.CENTROID_Y_COLUMN: y_coords_metres
    })

    rgb_matrix, colour_map_object, colour_norm_object = _process_colour_args(
        colour_map_object=colour_map_object,
        colour_min_unix_sec=colour_min_unix_sec,
        colour_max_unix_sec=colour_max_unix_sec,
        constant_colour=constant_colour,
        storm_object_table=storm_object_table
    )

    num_colours = None if rgb_matrix is None else rgb_matrix.shape[0]

    track_primary_id_strings, object_to_track_indices = numpy.unique(
        storm_object_table[tracking_utils.PRIMARY_ID_COLUMN].values,
        return_inverse=True
    )

    num_tracks = len(track_primary_id_strings)

    for j in range(num_tracks):
        these_object_indices = numpy.where(object_to_track_indices == j)[0]

        if colour_map_object is None:
            this_colour = rgb_matrix[numpy.mod(j, num_colours), :]
            this_colour = plotting_utils.colour_from_numpy_to_tuple(this_colour)

            axes_object.plot(
                x_coords_metres[these_object_indices],
                y_coords_metres[these_object_indices],
                linestyle='None', marker=marker_type,
                markersize=marker_size, markeredgewidth=0,
                markerfacecolor=this_colour, markeredgecolor=this_colour
            )

            continue

        for i in these_object_indices:
            this_colour = colour_map_object(colour_norm_object(
                storm_object_table[tracking_utils.VALID_TIME_COLUMN].values[i]
            ))
            this_colour = plotting_utils.colour_from_numpy_to_tuple(this_colour)

            axes_object.plot(
                x_coords_metres[i], y_coords_metres[i], linestyle='None',
                marker=marker_type, markersize=marker_size, markeredgewidth=0,
                markerfacecolor=this_colour, markeredgecolor=this_colour
            )

    if colour_map_object is None:
        return None

    return _add_colour_bar(
        axes_object=axes_object,
        basemap_object=basemap_object,
        colour_map_object=colour_map_object,
        colour_norm_object=colour_norm_object)
Example #28
0
def _plot_tornadoes(tornado_table, colour_map_object, colour_norm_object,
                    genesis_only, axes_object, basemap_object):
    """Plots start/end point of each tornado.

    :param tornado_table: pandas DataFrame returned by
        `linkage.read_linkage_file`.
    :param colour_map_object: Colour map (instance of `matplotlib.pyplot.cm`).
        Tornado markers will be coloured by time.
    :param colour_norm_object: Colour-normalizer (instance of
        `matplotlib.colors.Normalize`).  Used to convert from time to colour.
    :param genesis_only: See documentation at top of file.
    :param axes_object: Axes handle (instance of
        `matplotlib.axes._subplots.AxesSubplot`).
    :param basemap_object: Basemap handle (instance of
        `mpl_toolkits.basemap.Basemap`).
    """

    start_time_colour_matrix = colour_map_object(
        colour_norm_object(tornado_table[tornado_io.START_TIME_COLUMN].values))

    start_x_coords_metres, start_y_coords_metres = basemap_object(
        tornado_table[tornado_io.START_LNG_COLUMN].values,
        tornado_table[tornado_io.START_LAT_COLUMN].values)

    if genesis_only:
        end_time_colour_matrix = None
        end_x_coords_metres = None
        end_y_coords_metres = None
    else:
        end_time_colour_matrix = colour_map_object(
            colour_norm_object(
                tornado_table[tornado_io.END_TIME_COLUMN].values))

        end_x_coords_metres, end_y_coords_metres = basemap_object(
            tornado_table[tornado_io.END_LNG_COLUMN].values,
            tornado_table[tornado_io.END_LAT_COLUMN].values)

    num_tornadoes = len(tornado_table.index)

    for j in range(num_tornadoes):
        axes_object.plot(
            start_x_coords_metres[j],
            start_y_coords_metres[j],
            linestyle='None',
            marker=TORNADO_START_MARKER_TYPE,
            markersize=TORNADO_MARKER_SIZE,
            markeredgewidth=TORNADO_MARKER_EDGE_WIDTH,
            markerfacecolor=plotting_utils.colour_from_numpy_to_tuple(
                start_time_colour_matrix[j, :-1]),
            markeredgecolor='k')

        axes_object.text(start_x_coords_metres[j],
                         start_y_coords_metres[j],
                         tornado_table[SHORT_TORNADO_ID_COLUMN].values[j],
                         fontsize=TORNADO_FONT_SIZE,
                         color='k',
                         horizontalalignment='center',
                         verticalalignment='center')

        if genesis_only:
            continue

        axes_object.plot(
            end_x_coords_metres[j],
            end_y_coords_metres[j],
            linestyle='None',
            marker=TORNADO_END_MARKER_TYPE,
            markersize=TORNADO_MARKER_SIZE,
            markeredgewidth=TORNADO_MARKER_EDGE_WIDTH,
            markerfacecolor=plotting_utils.colour_from_numpy_to_tuple(
                end_time_colour_matrix[j, :-1]),
            markeredgecolor='k')

        axes_object.text(end_x_coords_metres[j],
                         end_y_coords_metres[j],
                         tornado_table[SHORT_TORNADO_ID_COLUMN].values[j],
                         fontsize=TORNADO_FONT_SIZE,
                         fontweight='bold',
                         color='k',
                         horizontalalignment='center',
                         verticalalignment='center')
Example #29
0
def plot_storm_tracks(
        storm_object_table, axes_object, basemap_object,
        colour_map_object='random',
        colour_min_unix_sec=None, colour_max_unix_sec=None,
        constant_colour=DEFAULT_TRACK_COLOUR, line_width=DEFAULT_TRACK_WIDTH,
        start_marker_type=DEFAULT_START_MARKER_TYPE,
        end_marker_type=DEFAULT_END_MARKER_TYPE,
        start_marker_size=DEFAULT_START_MARKER_SIZE,
        end_marker_size=DEFAULT_END_MARKER_SIZE):
    """Plots storm tracks.

    :param storm_object_table: See doc for `plot_storm_outlines`.
    :param axes_object: Same.
    :param basemap_object: Same.
    :param colour_map_object: See doc for `_process_colour_args`.
    :param colour_min_unix_sec: Same.
    :param colour_max_unix_sec: Same.
    :param constant_colour: Same.
    :param line_width: Track width.
    :param start_marker_type: Marker for beginning of each track.  If None,
        markers will not be plotted for beginning of track.
    :param end_marker_type: Same but for end of track.
    :param start_marker_size: Size of start-point marker.
    :param end_marker_size: Size of end-point marker.
    :return: colour_bar_object: Handle for colour bar.  If
        `colour_map_object is None`, this will also be None.
    """

    x_coords_metres, y_coords_metres = basemap_object(
        storm_object_table[tracking_utils.CENTROID_LONGITUDE_COLUMN].values,
        storm_object_table[tracking_utils.CENTROID_LATITUDE_COLUMN].values
    )

    storm_object_table = storm_object_table.assign(**{
        tracking_utils.CENTROID_X_COLUMN: x_coords_metres,
        tracking_utils.CENTROID_Y_COLUMN: y_coords_metres
    })

    rgb_matrix, colour_map_object, colour_norm_object = _process_colour_args(
        colour_map_object=colour_map_object,
        colour_min_unix_sec=colour_min_unix_sec,
        colour_max_unix_sec=colour_max_unix_sec,
        constant_colour=constant_colour,
        storm_object_table=storm_object_table
    )

    num_colours = None if rgb_matrix is None else rgb_matrix.shape[0]

    track_primary_id_strings, object_to_track_indices = numpy.unique(
        storm_object_table[tracking_utils.PRIMARY_ID_COLUMN].values,
        return_inverse=True
    )

    num_tracks = len(track_primary_id_strings)

    for j in range(num_tracks):
        if colour_map_object is None:
            this_colour = rgb_matrix[numpy.mod(j, num_colours), :]
            this_colour = plotting_utils.colour_from_numpy_to_tuple(this_colour)
        else:
            this_colour = None

        these_object_indices = numpy.where(object_to_track_indices == j)[0]
        storm_object_table_one_track = (
            storm_object_table.iloc[these_object_indices]
        )

        _plot_one_track(
            storm_object_table_one_track=storm_object_table_one_track,
            axes_object=axes_object, basemap_object=basemap_object,
            line_width=line_width, line_colour=this_colour,
            colour_map_object=colour_map_object,
            colour_norm_object=colour_norm_object)

        if start_marker_type is not None:
            _plot_start_or_end_markers(
                storm_object_table_one_track=storm_object_table_one_track,
                axes_object=axes_object, plot_at_start=True,
                marker_type=start_marker_type, marker_size=start_marker_size,
                track_colour=this_colour,
                colour_map_object=colour_map_object,
                colour_norm_object=colour_norm_object)

        if end_marker_type is not None:
            _plot_start_or_end_markers(
                storm_object_table_one_track=storm_object_table_one_track,
                axes_object=axes_object, plot_at_start=False,
                marker_type=end_marker_type, marker_size=end_marker_size,
                track_colour=this_colour,
                colour_map_object=colour_map_object,
                colour_norm_object=colour_norm_object)

    if colour_map_object is None:
        return None

    return _add_colour_bar(
        axes_object=axes_object,
        basemap_object=basemap_object,
        colour_map_object=colour_map_object,
        colour_norm_object=colour_norm_object)
Example #30
0
def _plot_linkages_one_storm_object(storm_to_tornadoes_table,
                                    storm_object_index,
                                    tornado_table,
                                    colour_map_object,
                                    colour_norm_object,
                                    axes_object,
                                    basemap_object,
                                    max_link_distance_metres=None):
    """Plots linkages for one storm object.

    :param storm_to_tornadoes_table: pandas DataFrame returned by
        `linkage.read_linkage_file`.
    :param storm_object_index: Will plot linkages for the [k]th storm object, or
        [k]th row of `storm_to_tornadoes_table`.
    :param tornado_table: pandas DataFrame returned by
        `linkage.read_linkage_file`.
    :param colour_map_object: Colour map (instance of `matplotlib.pyplot.cm`).
        Text boxes will be coloured by time.
    :param colour_norm_object: Colour-normalizer (instance of
        `matplotlib.colors.Normalize`).  Used to convert from time to colour.
    :param axes_object: Axes handle (instance of
        `matplotlib.axes._subplots.AxesSubplot`).
    :param basemap_object: Basemap handle (instance of
        `mpl_toolkits.basemap.Basemap`).
    :param max_link_distance_metres: See documentation at top of file.
    """

    i = storm_object_index

    linkage_distances_metres = storm_to_tornadoes_table[
        linkage.LINKAGE_DISTANCES_COLUMN].values[i]

    good_indices = numpy.where(
        linkage_distances_metres <= max_link_distance_metres)[0]

    if len(good_indices) == 0:
        return

    linked_id_strings = [
        storm_to_tornadoes_table[linkage.TORNADO_IDS_COLUMN].values[i][k]
        for k in good_indices
    ]

    linked_short_id_strings = []

    for this_id_string in linked_id_strings:
        these_indices = numpy.where(tornado_table[
            tornado_io.TORNADO_ID_COLUMN].values == this_id_string)[0]

        if len(these_indices) == 0:
            continue

        linked_short_id_strings.append(
            tornado_table[SHORT_TORNADO_ID_COLUMN].values[these_indices[0]])

    if len(linked_short_id_strings) == 0:
        return

    x_coord_metres, y_coord_metres = basemap_object(
        storm_to_tornadoes_table[
            tracking_utils.CENTROID_LONGITUDE_COLUMN].values[i],
        storm_to_tornadoes_table[
            tracking_utils.CENTROID_LATITUDE_COLUMN].values[i])

    bg_colour_numpy = colour_map_object(
        colour_norm_object(storm_to_tornadoes_table[
            tracking_utils.VALID_TIME_COLUMN].values[i]))

    bounding_box_dict = {
        'facecolor':
        plotting_utils.colour_from_numpy_to_tuple(bg_colour_numpy[:-1]),
        'alpha':
        LINKAGE_BACKGROUND_OPACITY,
        'edgecolor':
        'k',
        'linewidth':
        1
    }

    label_string = ','.join(list(set(linked_short_id_strings)))

    axes_object.text(x_coord_metres,
                     y_coord_metres,
                     label_string,
                     fontsize=LINKAGE_FONT_SIZE,
                     color=LINKAGE_FONT_COLOUR,
                     bbox=bounding_box_dict,
                     horizontalalignment='center',
                     verticalalignment='center',
                     zorder=1e10)