Skip to content

indicate_error for x direction #194

Closed

Description

@kinyatoride

Description

It would be really nice if indicate_error can also show error bars in x direction.

Steps to reproduce

import numpy as np
import proplot as plot

x = np.arange(10)
rng = np.random.default_rng()
y = rng.standard_normal((100, 10))

fig, ax = plot.subplots()
ax.plot(y, x, means=True)

Equivalent steps in matplotlib

errorbar has the xerr option to do this

Activity

  1. lukelbd commented on Jul 11, 2021

    @lukelbd
    Collaborator

    Added this as part of a giant refactor. Here's the massive new website example showcasing this:

    import proplot as plot
    import numpy as np
    import pandas as pd
    
    # Sample data
    state = np.random.RandomState(51423)
    data = state.rand(20, 8).cumsum(axis=0).cumsum(axis=1)[:, ::-1]
    data = data + 20 * state.normal(size=(20, 8)) + 30
    data = pd.DataFrame(data, columns=np.arange(0, 16, 2))
    data.columns.name = 'column number'
    data.name = 'variable'
    
    # Loop through "vertical" and "horizontal" versions
    array_vertical = [[1], [2], [3]]
    array_horizontal = [[1, 1], [2, 3], [2, 3]]
    for name, array in zip(('horizontal', 'vertical'), (array_horizontal, array_vertical)):
        # Figure
        fig, axs = plot.subplots(
            array, refaspect=1.5, refwidth=4,
            share=0, hratios=(2, 1, 1)
        )
        axs.format(abc=True, suptitle=f'Indicating {name} error bounds')
    
        # Medians and percentile ranges
        ax = axs[0]
        kw = dict(
            color='light red', legend=True,
            median=True, barpctile=90, boxpctile=True,
            # median=True, barpctile=(5, 95), boxpctile=(25, 75)  # equivalent
        )
        if name == 'horizontal':
            ax.barh(data, **kw)
        else:
            ax.bar(data, **kw)
        ax.format(title='Bar plot')
    
        # Means and standard deviation range
        ax = axs[1]
        kw = dict(
            color='denim', marker='x', markersize=8**2, linewidth=0.8,
            label='mean', shadelabel=True,
            mean=True, shadestd=1,
            # mean=True, shadestd=(-1, 1)  # equivalent
        )
        if name == 'horizontal':
            ax.scatterx(data, legend='b', legend_kw={'ncol': 1}, **kw)
        else:
            ax.scatter(data, legend='ll', **kw)
        ax.format(title='Marker plot')
    
        # User-defined error bars
        ax = axs[2]
        means = data.mean(axis=0)
        means.name = data.name
        shadedata = np.percentile(data, (25, 75), axis=0)  # dark shading
        fadedata = np.percentile(data, (5, 95), axis=0)  # light shading
        method = ax.plotx if name == 'horizontal' else ax.plot
        kw = dict(
            shadedata=shadedata, fadedata=fadedata,
            label='mean', shadelabel='50% CI', fadelabel='90% CI',
            color='ocean blue', barzorder=0, boxmarker=False,
        )
        if name == 'horizontal':
            ax.plotx(means, legend='b', legend_kw={'ncol': 1}, **kw)
        else:
            ax.plot(means, legend='ll', **kw)
        ax.format(title='Line plot')

    fancy_horizontal_error

  2. lukelbd commented on Jul 11, 2021

    @lukelbd
    Collaborator

    I went about this by adding plotx and scatterx commands (note the trailing x), analogous to fill_betweenx, hlines, and barh, that use the y axis as the dependent variable. They take input arguments as e.g. ax.plotx(y) or ax.plotx(y, x). Had been meaning to do this anyway! The website now showcases these commands under the "1D plotting" section.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions