# scipy.stats.circstd

scipy.stats.circstd(samples, high=6.283185307179586, low=0, axis=None, nan_policy='propagate', *, normalize=False)

  Compute the circular standard deviation for samples assumed to be in the range [low to high].

  Parameters:
    samples array_like

      Input array.

    high float or int, optional

      High boundary for the sample range. Default is `2*pi`.

    low float or int, optional

      Low boundary for the sample range. Default is 0.

    axis int, optional

      Axis along which standard deviations are computed. The default is to compute the standard deviation of the flattened array.

    nan_policy{‘propagate’, ‘raise’, ‘omit’}, optional

      Defines how to handle when input contains nan. ‘propagate’ returns nan, ‘raise’ throws an error, ‘omit’ performs the calculations ignoring nan values. Default is ‘propagate’.

    normalize boolean, optional

      If True, the returned value is equal to `sqrt(-2*log(R))` and does not depend on the variable units. If False (default), the returned value is scaled by `((high-low)/(2*pi))`.

  Returns:
    circstd float

      Circular standard deviation.

  See also

  `circmean`

    Circular mean.

  `circvar`

    Circular variance.

  Notes

  This uses a definition of circular standard deviation from [1]. Essentially, the calculation is as follows.

      import numpy as np
      C = np.cos(samples).mean()
      S = np.sin(samples).mean()
      R = np.sqrt(C**2 + S**2)
      l = 2*np.pi / (high-low)
      circstd = np.sqrt(-2*np.log(R)) / l

  In the limit of small angles, it returns a number close to the ‘linear’ standard deviation.

  References

  [1]

  Mardia, K. V. (1972). 2. In Statistics of Directional Data (pp. 18-24). Academic Press. DOI:10.1016/C2013-0-07425-7.

  Examples

      >>> import numpy as np
      >>> from scipy.stats import circstd
      >>> import matplotlib.pyplot as plt
      >>> samples_1 = np.array([0.072, -0.158, 0.077, 0.108, 0.286,
      ...                       0.133, -0.473, -0.001, -0.348, 0.131])
      >>> samples_2 = np.array([0.111, -0.879, 0.078, 0.733, 0.421,
      ...                       0.104, -0.136, -0.867,  0.012,  0.105])
      >>> circstd_1 = circstd(samples_1)
      >>> circstd_2 = circstd(samples_2)

  Plot the samples.

      >>> fig, (left, right) = plt.subplots(ncols=2)
      >>> for image in (left, right):
      ...     image.plot(np.cos(np.linspace(0, 2*np.pi, 500)),
      ...                np.sin(np.linspace(0, 2*np.pi, 500)),
      ...                c='k')
      ...     image.axis('equal')
      ...     image.axis('off')
      >>> left.scatter(np.cos(samples_1), np.sin(samples_1), c='k', s=15)
      >>> left.set_title(f"circular std: {np.round(circstd_1, 2)!r}")
      >>> right.plot(np.cos(np.linspace(0, 2*np.pi, 500)),
      ...            np.sin(np.linspace(0, 2*np.pi, 500)),
      ...            c='k')
      >>> right.scatter(np.cos(samples_2), np.sin(samples_2), c='k', s=15)
      >>> right.set_title(f"circular std: {np.round(circstd_2, 2)!r}")
      >>> plt.show()