Source code for pygeostat.plotting.probability_plot

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""A basic probability plotting routine reminiscent of probability_plot from gslib"""
#-----------------------------------------------------------------------------
# Boilerplate
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
from . set_style import set_plot_style


[docs] @set_plot_style def probability_plot(data, wt=None, lower=None, upper=None, logscale=True, ax=None, figsize=None, xlim=None, ylim=(0.01, 99.99), nyticks=15, title=None, xlabel=None, s=2, color='k', grid=True, axis_xy=None, line=False, plot_style=None, custom_style=None, output_file=None, out_kws=None, **kwargs): """ Create either a normal or a lognormal probability plot. This plot displays all the data values on a chart that illustrates the general distribution shape and the behavior of the extreme values. Please review the documentation of the :func:`gs.set_style() <pygeostat.plotting.set_style.set_style>` and :func:`gs.export_image() <pygeostat.plotting.export_image.export_image>` functions for details on their parameters so that their use in this function can be understood. This function requires the python package probscale. It can be installed be executing the following code in the command prompt: >>> pip install probscale Parameters: data: Tidy (long-form) 1D data where a single column of the variable exists with each row is an observation. A pandas dataframe/series or numpy array can be passed. wt: 1D dataframe, series, or numpy array of declustering weights for the data. lower (float): Lower trimming limits upper (float): Upper trimming limits ax (mpl.axis): Matplotlib axis to plot the figure figsize (tuple): Figure size (width, height) xlim (float tuple): Minimum and maximum limits of data along the x axis ylim (float tuple): Minimum and maximum limits of data along the y axis, e.g.(0.001, 99.999) nyticks (int): the number of ticks on the y axis to show. Currently disabled due to altered matplotlib functionality. title (str): Title for the plot xlabel (str): X-axis label. A default value of ``None`` will try and grab a label from the passed ``data``. Pass ``False`` to not have an xlabel. s (int): Size of points color (str or int): Any permissible matplotlib color or a integer which is used to draw a color from the pygeostat color pallet ``pallet_pastel`` (useful for iteration) grid(bool): plots the major grid lines if True. Based on gsParams['plotting.grid'] if None. axis_xy (bool): converts the axis to GSLIB-style axis visibility (only left and bottom visible) if axis_xy is True. Based on gsParams['plotting.axis_xy'] if None. plot_style (str): Use a predefined set of matplotlib plotting parameters as specified by :class:`gs.GridDef <pygeostat.data.grid_definition.GridDef>`. Use ``False`` or ``None`` to turn it off custom_style (dict): Alter some of the predefined parameters in the ``plot_style`` selected. output_file (str): Output figure file name and location out_kws (dict): Optional dictionary of permissible keyword arguments to pass to :func:`gs.export_image() <pygeostat.plotting.export_image.export_image>` **kwargs: Optional permissible keyword arguments to pass to matplotlib's scatter function Returns: ax (ax): matplotlib Axes object with the histogram **Examples:** A simple call: .. plot:: import pygeostat as gs data = gs.ExampleData('oilsands') gs.probability_plot(data.data['Fines'], logscale=False) """ # Import the rest of the packages import numpy as np import pandas as pd from .export_image import export_image from .. statistics.cdf import cdf import matplotlib.pyplot as plt from .utils import format_plot, get_label try: import probscale except ImportError: raise ImportError('Looks like probscale is not installed, use:\n' + '>>> pip install probscale\n') # Ensure valid VTK option # Coerce the passed data and wt into a single pandas dataframe if xlabel is None: xlabel = get_label(data) try: data = pd.DataFrame(data=data) data.reset_index(inplace=True, drop=True) if data.shape[1] != 1: raise ValueError("The passed `data` is not 1-D") except: raise ValueError("Please ensure the passed `data` can be coerced into a pandas dataframe" " (i.e., data = pd.DataFrame(data=data)") if wt is not None: try: wt = pd.DataFrame(data=wt) if wt.shape[1] != 1: raise ValueError("The passed `wt` is not 1-D") except: raise ValueError("Please ensure the passed `wt` can be coerced into a pandas" " dataframe (i.e., wt = pd.DataFrame(wt=wt)") else: wt = pd.DataFrame(data=np.ones((len(data), 1))) data = pd.concat([data, wt], axis=1) data.columns = ['data', 'wt'] # Trim the data if lower is None: lower = data['data'].min() if upper is None: upper = data['data'].max() data.query("%s <= data <= %s" % (lower, upper)) # Sanity checks assert((data['wt']).all() >= 0.0), 'Weights less than 0 not valid' # Handle dictionary defaults if out_kws is None: out_kws = dict() # Calculate the cdf cdf_x, cdfvals = cdf(data['data'], weights=data['wt']) cdfvals = cdfvals * 100 # Set-up plot if no axis is supplied if ax is None: _, ax = plt.subplots(figsize=figsize) # Plot the figure if line: ax.plot(cdf_x, cdfvals, color=color, **kwargs) else: ax.scatter(cdf_x, cdfvals, s=s, c=color, lw=0, **kwargs) # Set some figure aesthetics if logscale: ax.set_xscale('log') ax.set_yscale('prob') ax.locator_params(axis='y') ax = format_plot(ax, xlabel=xlabel, ylabel='Cumulative Probability', title=title, grid=grid, axis_xy=axis_xy, xlim=xlim, ylim=ylim) # Export figure if output_file or ('pdfpages' in out_kws): export_image(output_file, **out_kws) return ax