"""
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