def stat_fun(*args):
    # Inside the clustering function each condition will be passed as
    # flattened array, necessitated by the clustering procedure.
    # The ANOVA however expects an input array of dimensions:
    # subjects X conditions X observations (optional).
    # The following expression catches the list input
    # and swaps the first and the second dimension, and finally calls ANOVA.
    return f_twoway_rm(np.swapaxes(args, 1, 0), factor_levels=factor_levels,
                        effects=effects, return_pvals=return_pvals)[0]
def stat_fun(*args):
    # Inside the clustering function each condition will be passed as
    # flattened array, necessitated by the clustering procedure.
    # The ANOVA however expects an input array of dimensions:
    # subjects X conditions X observations (optional).
    # The following expression catches the list input and swaps the first and
    # the second dimension and finally calls the ANOVA function.
    return f_twoway_rm(np.swapaxes(args, 1, 0), factor_levels=factor_levels,
                       effects=effects, return_pvals=False)[0]
def stat_fun(*args):
    # Inside the clustering function each condition will be passed as
    # flattened array, necessitated by the clustering procedure.
    # The ANOVA however expects an input array of dimensions:
    # subjects X conditions X observations (optional).
    # The following expression catches the list input, swaps the first and the
    # second dimension and puts the remaining observations in the third
    # dimension.
    data = np.swapaxes(np.asarray(args), 1, 0).reshape(n_replications, n_conditions, n_times * n_frequencies)
    return f_twoway_rm(data, factor_levels=factor_levels, effects=effects, return_pvals=False)[0]
def stat_fun(*args):
    # Inside the clustering function each condition will be passed as
    # flattened array, necessitated by the clustering procedure.
    # The ANOVA however expects an input array of dimensions:
    # subjects X conditions X observations (optional).
    # The following expression catches the list input, swaps the first and the
    # second dimension and puts the remaining observations in the third
    # dimension.
    data = np.squeeze(np.swapaxes(np.array(args), 1, 0))
    data = data.reshape(n_subjects, n_conditions, data.size / (n_subjects * n_conditions))  # generalized if buffer used
    return f_twoway_rm(data, factor_levels=factor_levels, effects=effects, return_pvals=return_pvals)[0]
def stat_fun(*args):
    # Inside the clustering function each condition will be passed as
    # flattened array, necessitated by the clustering procedure.
    # The ANOVA however expects an input array of dimensions:
    # subjects X conditions X observations (optional).
    # The following expression catches the list input, swaps the first and the
    # second dimension and puts the remaining observations in the third
    # dimension.
    data = np.swapaxes(np.asarray(args), 1, 0).reshape(n_replications,
                                                       n_conditions,
                                                       n_times * n_frequencies)
    return f_twoway_rm(data, factor_levels=factor_levels,
                       effects=effects, return_pvals=False)[0]
# so we have replications * conditions * observations:
print(data.shape)

# while the iteration scheme used above for assembling the data matrix
# makes sure the first two dimensions are organized as expected (with A =
# modality and B = location):
#
#           A1B1 A1B2 A2B1 B2B2
# trial 1   1.34 2.53 0.97 1.74
# trial ... .... .... .... ....
# trial 56  2.45 7.90 3.09 4.76
#
# Now we're ready to run our repeated measures ANOVA.

fvals, pvals = f_twoway_rm(data, factor_levels, effects=effects)

effect_labels = ['modality', 'location', 'modality by location']
import matplotlib.pyplot as plt

# let's visualize our effects by computing f-images
for effect, sig, effect_label in zip(fvals, pvals, effect_labels):
    plt.figure()
    # show naive F-values in gray
    plt.imshow(effect.reshape(8, 211), cmap=plt.cm.gray, extent=[times[0],
               times[-1], frequencies[0], frequencies[-1]], aspect='auto',
               origin='lower')
    # create mask for significant Time-frequency locations
    effect = np.ma.masked_array(effect, [sig > .05])
    plt.imshow(effect.reshape(8, 211), cmap='RdBu_r', extent=[times[0],
               times[-1], frequencies[0], frequencies[-1]], aspect='auto',