def test_default(self): fig, ax = plt.subplots(5) share_axes(ax) for a in ax: self.assertTrue( all([i in a.get_shared_x_axes().get_siblings(a) for i in ax])) self.assertTrue( all([i in a.get_shared_y_axes().get_siblings(a) for i in ax]))
def test_which(self): for which, methods in [ ("xy", ["get_shared_x_axes", "get_shared_y_axes"]), ("x", ["get_shared_x_axes"]), ("y", ["get_shared_y_axes"]), ("both", ["get_shared_x_axes", "get_shared_y_axes"]), ]: with self.subTest(which=which, methods=methods): fig, ax = plt.subplots(5) share_axes(ax, which=which) for a in ax: for m in methods: self.assertTrue( all([ i in getattr(a, m)().get_siblings(a) for i in ax ])) plt.close("all")
# This function returns more than just the coordinates and histogram/density estimate, # which will come in handy for exploring how it came together. The data variable here # is a dictonary with contains the grids and coordiantes used to construct the # histogram/density diagram. We can use these to show how the ternary log-grid is # constructed, and then transformed back to ternary space before being triangulated # and interpoalted for the ternary heatmap: # import matplotlib.pyplot as plt import pyrolite.plot from pyrolite.util.math import flattengrid from pyrolite.util.plot.axes import axes_to_ternary, share_axes fig, ax = plt.subplots(3, 2, figsize=(6, 9)) ax = ax.flat share_axes([ax[1], ax[2], ax[3]]) ax = axes_to_ternary([ax[0], ax[4], ax[5]]) ax[0].set_title("data", y=1.2) df.pyroplot.scatter(ax=ax[0], c="k", alpha=0.1) ax[0].scatter(*data["tern_bound_points"].T, c="k") ax[1].set_title("transformed data", y=1.2) ax[1].scatter(*data["tfm_tern_bound_points"].T, c="k") ax[1].scatter(*data["grid_transform"](df.values).T, c="k", alpha=0.1) ax[2].set_title("log grid", y=1.2) ax[2].scatter(*flattengrid(data["tfm_centres"]).T, c="k", marker=".", s=5) ax[2].scatter(*flattengrid(data["tfm_edges"]).T, c="k", marker=".", s=2) ax[2].scatter(*data["tfm_tern_bound_points"].T, c="k")
# sets of synthetic REE patterns (lambda-only above and lamba+tetrad below) and examine # the relative accuracy of fitting some of the higher order lambda parameters where # tetrads are also fit: # from pyrolite.util.plot.axes import share_axes x, y = 2, 3 categories = np.repeat(np.arange(ls.shape[0]), 100) colors = np.array([str(ix) * 2 for ix in categories]) l_only = categories < 2 ax = plt.figure(figsize=(12, 7)).subplot_mosaic(""" AAABBCC DDDEEFF """) share_axes([ax["A"], ax["D"]]) share_axes([ax["B"], ax["C"], ax["E"], ax["F"]]) ax["B"].set_title("lambdas only Fit") ax["C"].set_title("lambdas+tetrads Fit") for a, fltr in zip(["A", "D"], [l_only, ~l_only]): pattern_df.iloc[fltr, :].pyroplot.spider( ax=ax[a], label="True", unity_line=True, alpha=0.5, color=colors[fltr], ) for a, fltr in zip(["B", "E"], [l_only, ~l_only]):
from pyrolite.util.plot.axes import share_axes # sphinx_gallery_thumbnail_number = 2 ax = TAS(linewidth=0.5, add_labels=True) plt.show() ######################################################################################## # The other templates currently included in :mod:`pyrolite` are the # :func:`~pyrolite.plot.templates.pearceThNbYb` and # :func:`~pyrolite.plot.templates.pearceTiNbYb` diagrams. # We can create some axes and add these templates to them: # from pyrolite.plot.templates import pearceThNbYb, pearceTiNbYb fig, ax = plt.subplots(1, 2, figsize=(10, 4)) share_axes(ax, which="x") # these diagrams have the same x axis pearceThNbYb(ax=ax[0]) pearceTiNbYb(ax=ax[1]) plt.tight_layout() # nicer spacing for axis labels ######################################################################################## # Ternary Templates # ~~~~~~~~~~~~~~~~~~ # pyrolite now also includes ternary classification diagrams inlcuding # the :func:`~pyrolite.plot.templates.QAP` and # :func:`~pyrolite.plot.templates.USDASoilTexture` diagrams: # from pyrolite.plot.templates import QAP, FeldsparTernary, USDASoilTexture ax = QAP(linewidth=0.4)
fig, ax = plt.subplots(2, 2, sharex=True, sharey=True) plt.show() ####################################################################################### # However, if you want to share axes in a way which is less standard, it can be # difficult to set up using this function. :mod:`pyrolite` has a utility function # which can be used to share axes after they're created in slightly more arbitrary # ways. For example, imagine we wanted to share the first and third x-axes, and the # first three y-axes, you could use: # import matplotlib.pyplot as plt from pyrolite.util.plot.axes import share_axes fig, ax = plt.subplots(2, 2) ax = ax.flat # turn the (2,2) array of axes into one flat axes with shape (4,) share_axes([ax[0], ax[2]], which="x") # share x-axes for 0, 2 share_axes(ax[0:3], which="y") # share y-axes for 0, 1, 2 ax[0].set_xlim((0, 10)) ax[1].set_ylim((-5, 5)) plt.show() ####################################################################################### # Legends # ------- # # While it's simple to set up basic legends in :mod:`maplotlib` (see the docs for # :func:`matplotlib.axes.Axes.legend`), often you'll want to customise # your legends to fit nicely within your figures. Here we'll create a few # synthetic datasets, add them to a figure and create the default legend: import pyrolite.plot import matplotlib.pyplot as plt
df = normal_frame( size=1000, cov=random_cov_matrix(sigmas=np.random.rand(4) * 2, dim=4, seed=12), seed=12, ) ######################################################################################## # We can compare a minimal :func:`~pyrolite.plot.pyroplot.heatscatter` plot to other # visualisations for the same data: # from pyrolite.util.plot.axes import share_axes fig, ax = plt.subplots(3, 4, figsize=(12, 9)) ax = ax.flat share_axes(ax[:4], which="xy") share_axes(ax[4:8], which="xy") share_axes(ax[8:], which="xy") contours = [0.95, 0.66, 0.3] bivar = ["SiO2", "MgO"] trivar = ["SiO2", "MgO", "TiO2"] # linear-scaled comparison df.loc[:, bivar].pyroplot.scatter(ax=ax[0], c="k", s=10, alpha=0.3) df.loc[:, bivar].pyroplot.density(ax=ax[1]) df.loc[:, bivar].pyroplot.density(ax=ax[2], contours=contours) df.loc[:, bivar].pyroplot.heatscatter(ax=ax[3], s=10, alpha=0.3) # log-log plots df.loc[:, bivar].pyroplot.scatter(ax=ax[4], c="k", s=10, alpha=0.3) df.loc[:, bivar].pyroplot.density(ax=ax[5], logx=True, logy=True) df.loc[:, bivar].pyroplot.density(ax=ax[6],
# starting from a normal distribution, then creating similar non-normal distributions mean, sd = 2.5, 1.5 # logmu, logs = norm_to_lognorm(mean, sd) # parameters for equival normrv = norm(loc=mean, scale=sd) lognormrv = lognorm(s=logs, scale=logmu) poissonrv = poisson(mu=mean) ######################################################################################## # We can visualise the similarities and differences between these distributions: # fig, ax = plt.subplots(2, 3, figsize=(8, 4)) ax = ax.flat for a in ax: a.subax = subaxes(a, side="bottom") share_axes(ax[:3], which="x") share_axes(ax[3:], which="x") ax[0].set_xlim(-2, 10) ax[3].set_xscale("log") ax[3].set_xlim(0.1, 10) for a in ax: a.axvline(0, color="k", lw=0.5, ls="--") # xs at which to evaluate the pdfs x = np.linspace(-5, 15.0, 1001) for ix, dist in enumerate([normrv, lognormrv, poissonrv]): _xs = dist.rvs(size=10000) # random sample _ys = -0.05 + np.random.randn( 10000) / 100 # random offsets for visualisation