Source code for SALib.plotting.morris

"""
Created on 29 Jun 2015

@author: @willu47

This module provides the basic infrastructure for plotting charts for the
Method of Morris results

The procedures should build upon and return an axes instance::

    import matplotlib.pyplot as plt
    Si = morris.analyze(problem, param_values, Y, conf_level=0.95,
                        print_to_console=False, num_levels=10)

    # set plot style etc.
    fig, ax = plt.subplots(1)
    p = SALib.plotting.morris.horizontal_bar_plot(ax, Si, {'marker':'x'})
    p.show()
"""

import numpy as np


def _sort_Si(Si, key, sortby="mu_star"):
    return np.array([Si[key][x] for x in np.argsort(Si[sortby])])


def _sort_Si_by_index(Si, key, index):
    return np.array([Si[key][x] for x in index])


[docs] def horizontal_bar_plot(ax, Si, opts=None, sortby="mu_star", unit=""): """Updates a matplotlib axes instance with a horizontal bar plot of mu_star, with error bars representing mu_star_conf. """ assert sortby in ["mu_star", "mu_star_conf", "sigma", "mu"] if opts is None: opts = {} # Sort all the plotted elements by mu_star (or optionally another # metric) names_sorted = _sort_Si(Si, "names", sortby) mu_star_sorted = _sort_Si(Si, "mu_star", sortby) mu_star_conf_sorted = _sort_Si(Si, "mu_star_conf", sortby) # Plot horizontal barchart y_pos = np.arange(len(mu_star_sorted)) plot_names = names_sorted out = ax.barh( y_pos, mu_star_sorted, xerr=mu_star_conf_sorted, align="center", ecolor="black", **opts, ) ax.set_yticks(y_pos) ax.set_yticklabels(plot_names) ax.set_xlabel(r"$\mu^\star$" + unit) ax.set_ylim(min(y_pos) - 1, max(y_pos) + 1) return out
[docs] def covariance_plot(ax, Si, opts=None, unit=""): """Plots mu* against sigma or the 95% confidence interval""" if opts is None: opts = {} if Si["sigma"] is not None: # sigma is not present if using morris groups y = Si["sigma"] out = ax.scatter(Si["mu_star"], y, c="k", marker="o", **opts) ax.set_ylabel(r"$\sigma$") ax.set_xlim( 0, ) ax.set_ylim( 0, ) x_axis_bounds = np.array(ax.get_xlim()) (line1,) = ax.plot(x_axis_bounds, x_axis_bounds, "k-") (line2,) = ax.plot(x_axis_bounds, 0.5 * x_axis_bounds, "k--") (line3,) = ax.plot(x_axis_bounds, 0.1 * x_axis_bounds, "k-.") ax.legend( (line1, line2, line3), ( r"$\sigma / \mu^{\star} = 1.0$", r"$\sigma / \mu^{\star} = 0.5$", r"$\sigma / \mu^{\star} = 0.1$", ), loc="best", ) else: y = Si["mu_star_conf"] out = ax.scatter(Si["mu_star"], y, c="k", marker="o", **opts) ax.set_ylabel(r"$95\% CI$") ax.set_xlabel(r"$\mu^\star$ " + unit) ax.set_ylim( 0 - (0.01 * np.array(ax.get_ylim()[1])), ) return out
[docs] def sample_histograms(fig, input_sample, problem, opts=None): """Plots a set of subplots of histograms of the input sample""" if opts is None: opts = {} num_vars = problem["num_vars"] names = problem["names"] framing = 101 + (num_vars * 10) # Find number of levels num_levels = len(set(input_sample[:, 1])) out = [] for variable in range(num_vars): ax = fig.add_subplot(framing + variable) out.append( ax.hist( input_sample[:, variable], bins=num_levels, density=False, label=None, **opts, ) ) ax.set_title("%s" % (names[variable])) ax.tick_params( axis="x", # changes apply to the x-axis which="both", # both major and minor ticks are affected bottom="off", # ticks along the bottom edge are off top="off", # ticks along the top edge are off labelbottom="off", ) # labels along the bottom edge off) if variable > 0: ax.tick_params( axis="y", # changes apply to the y-axis which="both", # both major and minor ticks affected labelleft="off", ) # labels along the left edge off) return out
if __name__ == "__main__": pass