import numpy as np
from pycircstat2 import Circular, load_data
Chapter 27 of Zar (2010) contains many examples and step-by-step guide of how to compute most of circular hypothesis testing. We replicated all those examples and figures in notebook B2-Zar-2010
with pycircstats2
.
rayleigh_test(alpha)
tests $H_{0}: \rho=0$ vs. $H_{A}: \rho \neq 0$, where $\rho$ is the population mean vector length. If the Rayleigh Test rejects $H_0$ ($p<0.05$), then the population is not a uniform circular distribution, or there is a mean population direction.
NOTE: The Rayleigh Test assumes the data is unimodal.
from pycircstat2.hypothesis import rayleigh_test
d1 = load_data('D1', source='zar')['θ'].values
c1 = Circular(data=d1)
z, pval = rayleigh_test(c1.alpha, verbose=True)
Rayleigh's Test of Uniformity ----------------------------- H0: ρ = 0 HA: ρ ≠ 0 Test Statistics: 5.44787 P-value: 0.00185 **
V_test(angle, alpha)
is a modified Rayleigh test that tests $H_{0}: \rho=0$ vs. $H_{A}: \rho \neq 0$ and has a mean angle ($\mu$).
from pycircstat2.hypothesis import V_test
d7 = load_data('D7', source='zar')['θ'].values
c7 = Circular(data=d7)
V, u, pval = V_test(angle=np.deg2rad(90), alpha=c7.alpha, verbose=True)
Modified Rayleigh's Test of Uniformity -------------------------------------- H0: ρ = 0 HA: ρ ≠ 0 and μ = 1.57080 rad Test Statistics: 9.49761 P-value: 0.00001 ***
omnibus_test(alpha)
tests $H_0$: uniform vs. $H_A$: not unifrom. Also called Ajne's A Test, or "omnibus test" because it works well for unimodal, bimodal, and multimoodal distributions.
from pycircstat2.hypothesis import omnibus_test
d8 = load_data('D8', source='zar')['θ'].values
c8 = Circular(data=d8)
A, pval = omnibus_test(c8.alpha, verbose=True)
Hodges-Ajne ("omnibus") Test for Uniformity ------------------------------------------- H0: uniform HA: not unifrom Test Statistics: 0.42752 P-value: 0.00434 **
batschelet_test(alpha)
is a modified Hodges-Ajne Test that tests $H_0$: uniform vs. $H_A$: not unifrom but concentrated around an angle θ.
from pycircstat2.hypothesis import batschelet_test
C, pval = batschelet_test(angle=np.deg2rad(45), alpha=c8.alpha, verbose=True)
Batschelet Test for Uniformity ------------------------------ H0: uniform HA: not unifrom but concentrated around θ = 0.78540 rad Test Statistics: 5 P-value: 0.00661 **
chisquare_test(alpha)
tests the goodness of fit of a theoretical circular frequency distribution to an observed one. Here it is used to test whether the data in the population are distributed unifromly around the circle. This method is for grouped data.
from pycircstat2.hypothesis import chisquare_test
d2 = load_data("D2", source="zar")
c2 = Circular(data=d2["θ"].values, w=d2["w"].values)
chi2, pval = chisquare_test(c2.w, verbose=True)
Chi-Square Test of Uniformity ----------------------------- H0: uniform HA: not uniform Test Statistics: 66.54286 P-value: 0.00000 ***
kuiper_test(alpha)
, watson_test(alpha)
, and raospacing_test(alpha)
are Goodness-of-fit tests for ungrouped data. P-values for these tests are computed through simulation.
from pycircstat2.hypothesis import kuiper_test, watson_test, rao_spacing_test
pigeon = np.array([20, 135, 145, 165, 170, 200, 300, 325, 335, 350, 350, 350, 355])
c_pigeon = Circular(data=pigeon)
V, pval = kuiper_test(c_pigeon.alpha, n_simulation=9999, verbose=True)
Kuiper's Test of Circular Uniformity ------------------------------------ Test Statistic: 1.5047 P-value = 0.1691
U2, pval = watson_test(c_pigeon.alpha, n_simulation=9999, verbose=True)
Watson's One-Sample U2 Test of Circular Uniformity -------------------------------------------------- Test Statistic: 0.1361 P-value = 0.1369
U, pval = rao_spacing_test(c_pigeon.alpha, n_simulation=9999, verbose=True)
Rao's Spacing Test of Circular Uniformity ----------------------------------------- Test Statistic: 2.8261 P-value = 0.0766
symmetry_test(alpha)
tests $H_0$: symmetrical around $\theta$ vs. $H_A$: not symmetrical around $\theta$, where $\theta$ is the median of the population.
from pycircstat2.hypothesis import symmetry_test
d9 = load_data('D9', source='zar')['θ'].values
c9 = Circular(data=d9)
statistics, pval = symmetry_test(alpha=c9.alpha, verbose=True)
Symmetry Test ------------------------------ H0: symmetrical around median HA: not symmetrical around median Test Statistics: 14.50000 P-value: 0.74219
one_sample_test(alpha)
tests $H_{0}: \mu_a=\mu_0$ vs. $H_{A}: \mu_a \neq \mu_0$ ,where $\mu_{a}$ is the population mean angle and $\mu_{0}$ is a specified angle. This test is simply observing whether $\mu_{0}$ lies within the confidence interval for $\mu_{a}$.
from pycircstat2.hypothesis import one_sample_test
reject_or_not = one_sample_test(angle=np.deg2rad(90), alpha=c7.alpha, verbose=True)
One-Sample Test for the Mean Angle ---------------------------------- H0: μ = μ0 HA: μ ≠ μ0 and μ0 = 1.57080 rad Failed to reject H0: μ0 = 1.57080 lies within the 95% CI of μ ([1.41993 1.86297])
watson_williams_test(circs)
tests $H_0$: $\mu_1 = \mu_2 = ... = \mu_n$ vs. $H_A$: $\mu_1 \neq \mu_2 \neq ... \neq \mu_n$
from pycircstat2.hypothesis import watson_williams_test
data = load_data("D11", source="zar")
s1 = Circular(data=data[data["sample"] == 1]["θ"].values)
s2 = Circular(data=data[data["sample"] == 2]["θ"].values)
s3 = Circular(data=data[data["sample"] == 3]["θ"].values)
F, pval = watson_williams_test(circs=[s1, s2, s3], verbose=True)
The Watson-Williams Test for multiple samples --------------------------------------------- H0: all samples are from populations with the same angle. HA: all samples are not from populations with the same angle. Test Statistics: 1.86524 P-value: 0.18701
watson_U2_test(circs)
tests $H_0$: $\mu_1 = \mu_2 = ... = \mu_n$ vs. $H_A$: $\mu_1 \neq \mu_2 \neq ... \neq \mu_n$ for data with or without ties
from pycircstat2.hypothesis import watson_u2_test
# without ties
d = load_data("D12", source="zar")
c0 = Circular(data=d[d["sample"] == 1]["θ"].values)
c1 = Circular(data=d[d["sample"] == 2]["θ"].values)
U2, pval = watson_u2_test(circs=[c0, c1], verbose=True)
Watson's U2 Test for two samples --------------------------------------------- H0: The two samples are from populations with the same angle. HA: The two samples are not from populations with the same angle. Test Statistics: 0.14574 P-value: 0.11261
# with ties
d = load_data("D13", source="zar")
c0 = Circular(data=d[d["sample"] == 1]["θ"].values, w=d[d["sample"] == 1]["w"].values)
c1 = Circular(data=d[d["sample"] == 2]["θ"].values, w=d[d["sample"] == 2]["w"].values)
U2, pval = watson_u2_test(circs=[c0, c1], verbose=True)
Watson's U2 Test for two samples --------------------------------------------- H0: The two samples are from populations with the same angle. HA: The two samples are not from populations with the same angle. Test Statistics: 0.06123 P-value: 0.59716
wheeler_watson_test(circs)
tests $H_0$: $\mu_1 = \mu_2 = ... = \mu_n$ vs. $H_A$: $\mu_1 \neq \mu_2 \neq ... \neq \mu_n$.
from pycircstat2.hypothesis import wheeler_watson_test
d = load_data("D12", source="zar")
c0 = Circular(data=d[d["sample"] == 1]["θ"].values)
c1 = Circular(data=d[d["sample"] == 2]["θ"].values)
W, pval = wheeler_watson_test(circs=[c0, c1], verbose=True)
The Wheeler and Watson Two/Multi-Sample Test --------------------------------------------- H0: All samples are from populations with the same angle. HA: All samples are not from populations with the same angle. Test Statistics: 3.67827 P-value: 0.15895
from pycircstat2.hypothesis import wallraff_test
d = load_data("D14", source="zar")
c0 = Circular(data=d[d["sex"] == "male"]["θ"].values)
c1 = Circular(data=d[d["sex"] == "female"]["θ"].values)
U, pval = wallraff_test(angle=np.deg2rad(135), circs=[c0, c1], verbose=True)
Wallraff test of angular distances / dispersion ----------------------------------------------- Test Statistics: 18.50000 P-value: 0.77510
from pycircstat2.utils import time2float
d = load_data("D15", source="zar")
c0 = Circular(data=time2float(d[d["sex"] == "male"]["time"].values))
c1 = Circular(data=time2float(d[d["sex"] == "female"]["time"].values))
U, pval = wallraff_test(angle=np.deg2rad(time2float(['7:55', '8:15'])), circs=[c0, c1], verbose=True)
Wallraff test of angular distances / dispersion ----------------------------------------------- Test Statistics: 13.00000 P-value: 0.17524
%load_ext watermark
%watermark --time --date --timezone --updated --python --iversions --watermark -p pycircstat2
Last updated: 2024-11-21 16:44:43CET Python implementation: CPython Python version : 3.10.13 IPython version : 8.29.0 pycircstat2: 0.1.0 pycircstat2: 0.1.0 numpy : 2.1.3 Watermark: 2.5.0