# Path: jr/stats/circ.py
# def circ_shift(alpha, shift, wrapped=True):
#     alpha = np.array(alpha)
#     dims = alpha.shape
#     alpha = np.reshape(alpha, [len(alpha), -1])
#     bins = np.linspace(0, 2 * np.pi, len(alpha))
#     shift = np.where(bins >= shift)[0][0]
#     if wrapped:
#         alpha = np.vstack((alpha[shift:-1, :], alpha[:shift, :],
#                            alpha[shift, :]))
#     else:
#         alpha = np.vstack((alpha[shift:, :], alpha[:shift, :]))
#     alpha = np.reshape(alpha, dims)
#     return alpha
# 
# def circ_double_tuning(radius, bins, wrapped=True):
#     radius = np.array(radius)
#     bins = np.array(bins)
#     dims = radius.shape
#     if dims[0] != 2:
#         radius = np.reshape(radius, [len(radius), -1])
#     if wrapped:
#         bins = np.hstack((bins[:-1] / 2, np.pi + bins[:-1] / 2, bins[0]))
#         radius = np.vstack((radius[:-1, :], radius))
#     else:
#         bins = np.hstack((bins / 2, np.pi + bins / 2, bins[0]))
#         radius = np.vstack((radius, radius, radius[0, :]))
#     shape = np.hstack((dims[0] * 2 - 1, dims[1:]))
#     radius = np.reshape(radius, shape.astype(int))
#     return radius, bins
# 
# Path: jr/plot/base.py
# def plot_sem(x, y, robust=False, **kwargs):
#     """
#     Parameters
#     ----------
#     x : list | np.array()
#     y : list | np.array()
#     robust : bool
#         If False use mean + std,
#         If True median + mad
#     ax
#     alpha
#     color
#     line_args
#     err_args
# 
#     Returns
#     -------
#     ax
# 
#     Adapted from http://tonysyu.github.io/plotting-error-bars.html#.VRE9msvmvEU
#     """
#     x, y = np.array(x), np.array(y)
#     if robust:
#         m = np.nanmedian(y, axis=0)
#         std = median_abs_deviation(y, axis=0)
#     else:
#         m = np.nanmean(y, axis=0)
#         std = np.nanstd(y, axis=0)
#     n = y.shape[0] - np.sum(np.isnan(y), axis=0)
# 
#     return plot_eb(x, m, std / np.sqrt(n), **kwargs)
# 
# def pretty_plot(ax=None):
#     if ax is None:
#         plt.gca()
#     ax.tick_params(colors='dimgray')
#     ax.xaxis.label.set_color('dimgray')
#     ax.yaxis.label.set_color('dimgray')
#     try:
#         ax.zaxis.label.set_color('dimgray')
#     except AttributeError:
#         pass
#     try:
#         ax.xaxis.set_ticks_position('bottom')
#         ax.yaxis.set_ticks_position('left')
#     except ValueError:
#         pass
#     ax.spines['left'].set_color('dimgray')
#     ax.spines['bottom'].set_color('dimgray')
#     ax.spines['right'].set_visible(False)
#     ax.spines['top'].set_visible(False)
#     return ax
# 
# Path: jr/utils.py
# def pi_labels(X):
#     from numpy import pi
#     if len(np.shape(X)) == 0:
#         X = [X]
#     d = {0: r'0', pi: r'$\pi$', 2*pi: r'$2\pi$', pi/2: r'$\pi/2$',
#          3*pi/2: r'$3\pi/2$', pi/4: r'$\pi/4$', 3*pi/4: r'$3\pi/4$',
#          pi/3: r'$\pi/3$'}
#     labels = list()
#     for x in X:
#         if isinstance(x, str):
#             labels.append(x)
#         elif x in d.keys():
#             labels.append(d[x])
#         elif -x in d.keys():
#             labels.append(r'-' + d[-x])
#         else:
#             labels.append(r'%.2f' % x)
#     return labels


import numpy as np
import matplotlib.pyplot as plt
from ..stats.circ import circ_shift, circ_double_tuning
from .base import plot_sem, pretty_plot
from ..utils import pi_labels
        bins = bins - shift
    if chance == 'auto':
        chance = 1. / nbin
    if ylim == 'auto':
        ylim = [min(data.mean(0) - data.std(0) / np.sqrt(len(data))),
                max(data.mean(0) + data.std(0) / np.sqrt(len(data)))]
    if polar:
        bins = np.hstack((bins, bins[0]))
        data = np.hstack((data, data[:, 0, None]))
        if half:
            data, bins = circ_double_tuning(data.T, bins)
            data = data.T
        ax = plot_sem_polar(bins, data, color=color, alpha=alpha, fill=False,
                            ax=ax)
        if chance is not None:
            ax.fill_between(
                np.hstack((bins, bins[-1::-1])),
                np.hstack((chance * np.ones(len(bins)), data.mean(0)[-1::-1])),
                facecolor=color, edgecolor='none', alpha=alpha)
        pretty_polar_plot(ax)
        ax.set_xticks([-np.pi, 0, np.pi])
        ax.set_xticklabels(pi_labels([-np.pi, 0, np.pi]))
    else:
        ax = plot_sem(bins, data, ax=ax, color=color, alpha=alpha)
        if chance is not None:
            ax.fill_between(
                np.hstack((bins[0], bins, bins[-1], bins[0])),
                np.hstack((chance, data.mean(0), chance, chance)),
                facecolor=color, edgecolor='none', alpha=alpha)
        ax.set_xlim(bins[0], bins[-1])

# Path: jr/stats/circ.py
# def circ_shift(alpha, shift, wrapped=True):
#     alpha = np.array(alpha)
#     dims = alpha.shape
#     alpha = np.reshape(alpha, [len(alpha), -1])
#     bins = np.linspace(0, 2 * np.pi, len(alpha))
#     shift = np.where(bins >= shift)[0][0]
#     if wrapped:
#         alpha = np.vstack((alpha[shift:-1, :], alpha[:shift, :],
#                            alpha[shift, :]))
#     else:
#         alpha = np.vstack((alpha[shift:, :], alpha[:shift, :]))
#     alpha = np.reshape(alpha, dims)
#     return alpha
# 
# def circ_double_tuning(radius, bins, wrapped=True):
#     radius = np.array(radius)
#     bins = np.array(bins)
#     dims = radius.shape
#     if dims[0] != 2:
#         radius = np.reshape(radius, [len(radius), -1])
#     if wrapped:
#         bins = np.hstack((bins[:-1] / 2, np.pi + bins[:-1] / 2, bins[0]))
#         radius = np.vstack((radius[:-1, :], radius))
#     else:
#         bins = np.hstack((bins / 2, np.pi + bins / 2, bins[0]))
#         radius = np.vstack((radius, radius, radius[0, :]))
#     shape = np.hstack((dims[0] * 2 - 1, dims[1:]))
#     radius = np.reshape(radius, shape.astype(int))
#     return radius, bins
# 
# Path: jr/plot/base.py
# def plot_sem(x, y, robust=False, **kwargs):
#     """
#     Parameters
#     ----------
#     x : list | np.array()
#     y : list | np.array()
#     robust : bool
#         If False use mean + std,
#         If True median + mad
#     ax
#     alpha
#     color
#     line_args
#     err_args
# 
#     Returns
#     -------
#     ax
# 
#     Adapted from http://tonysyu.github.io/plotting-error-bars.html#.VRE9msvmvEU
#     """
#     x, y = np.array(x), np.array(y)
#     if robust:
#         m = np.nanmedian(y, axis=0)
#         std = median_abs_deviation(y, axis=0)
#     else:
#         m = np.nanmean(y, axis=0)
#         std = np.nanstd(y, axis=0)
#     n = y.shape[0] - np.sum(np.isnan(y), axis=0)
# 
#     return plot_eb(x, m, std / np.sqrt(n), **kwargs)
# 
# def pretty_plot(ax=None):
#     if ax is None:
#         plt.gca()
#     ax.tick_params(colors='dimgray')
#     ax.xaxis.label.set_color('dimgray')
#     ax.yaxis.label.set_color('dimgray')
#     try:
#         ax.zaxis.label.set_color('dimgray')
#     except AttributeError:
#         pass
#     try:
#         ax.xaxis.set_ticks_position('bottom')
#         ax.yaxis.set_ticks_position('left')
#     except ValueError:
#         pass
#     ax.spines['left'].set_color('dimgray')
#     ax.spines['bottom'].set_color('dimgray')
#     ax.spines['right'].set_visible(False)
#     ax.spines['top'].set_visible(False)
#     return ax
# 
# Path: jr/utils.py
# def pi_labels(X):
#     from numpy import pi
#     if len(np.shape(X)) == 0:
#         X = [X]
#     d = {0: r'0', pi: r'$\pi$', 2*pi: r'$2\pi$', pi/2: r'$\pi/2$',
#          3*pi/2: r'$3\pi/2$', pi/4: r'$\pi/4$', 3*pi/4: r'$3\pi/4$',
#          pi/3: r'$\pi/3$'}
#     labels = list()
#     for x in X:
#         if isinstance(x, str):
#             labels.append(x)
#         elif x in d.keys():
#             labels.append(d[x])
#         elif -x in d.keys():
#             labels.append(r'-' + d[-x])
#         else:
#             labels.append(r'%.2f' % x)
#     return labels


# Path: jr/plot/circ.py
import numpy as np
import matplotlib.pyplot as plt
from ..stats.circ import circ_shift, circ_double_tuning
from .base import plot_sem, pretty_plot
from ..utils import pi_labels

        bins = bins - shift
    if chance == 'auto':
        chance = 1. / nbin
    if ylim == 'auto':
        ylim = [min(data.mean(0) - data.std(0) / np.sqrt(len(data))),
                max(data.mean(0) + data.std(0) / np.sqrt(len(data)))]
    if polar:
        bins = np.hstack((bins, bins[0]))
        data = np.hstack((data, data[:, 0, None]))
        if half:
            data, bins = circ_double_tuning(data.T, bins)
            data = data.T
        ax = plot_sem_polar(bins, data, color=color, alpha=alpha, fill=False,
                            ax=ax)
        if chance is not None:
            ax.fill_between(
                np.hstack((bins, bins[-1::-1])),
                np.hstack((chance * np.ones(len(bins)), data.mean(0)[-1::-1])),
                facecolor=color, edgecolor='none', alpha=alpha)
        pretty_polar_plot(ax)
        ax.set_xticks([-np.pi, 0, np.pi])
        ax.set_xticklabels(pi_labels([-np.pi, 0, np.pi]))
    else:
        ax = plot_sem(bins, data, ax=ax, color=color, alpha=alpha)
        if chance is not None:
            ax.fill_between(
                np.hstack((bins[0], bins, bins[-1], bins[0])),
                np.hstack((chance, data.mean(0), chance, chance)),
                facecolor=color, edgecolor='none', alpha=alpha)
        ax.set_xlim(bins[0], bins[-1])

        pretty_plot(ax)