Skip to content

Instantly share code, notes, and snippets.

@cwindolf
cwindolf / ciline.py
Created September 12, 2024 21:01
Plot moving means and standard deviations
def sliding_mean_and_stddev_interval(
axis, xs, ys, n_neighbors=30, linewidth=1, color="k", ci_alpha=0.25
):
"""Plot moving means and standard deviations"""
_1 = np.ones(2 * n_neighbors + 1)
_ys = np.nan_to_num(ys)
sliding_sum = correlate1d(_ys, _1, mode="constant")
sliding_N = correlate1d(np.isfinite(ys).astype(float), _1, mode="constant")
sliding_mean = sliding_sum / sliding_N
sliding_sumsq = correlate1d(_ys**2, _1, mode="constant")
@cwindolf
cwindolf / ppca.py
Last active April 11, 2024 15:18
Probabilistic PCA in PyTorch with missing data. See the very nice JMLR paper of Ilin and Raiko in 2010.
import torch
from torch import nn
from tqdm.auto import trange
class PPCA(nn.Module):
def __init__(self, d, c):
super().__init__()
self.d = d
self.c = c
@cwindolf
cwindolf / matplotlib_contextmanagers.py
Created June 21, 2023 17:27
Matplotlib context manager helpers
import matplotlib.pyplot as plt
import contextlib
@contextlib.contextmanager
def subplots(*args, **kwargs):
fig, axes = plt.subplots(*args, **kwargs)
try:
yield fig, axes
finally:
plt.show()
def runs_to_ranges(x, one_more=False):
ranges = []
cur = x[0]
b = x[0]
for a, b in zip(x, x[1:]):
assert b > a
if b - a == 1:
continue
else:
ranges.append(range(cur, a + 1 + one_more))
@cwindolf
cwindolf / matplotlib_preamble_sans.py
Last active September 22, 2023 16:51
Example matplotlib config with latex fonts
%config InlineBackend.figure_format = 'retina'
import matplotlib.pyplot as plt
from matplotlib.markers import MarkerStyle
from matplotlib.transforms import offset_copy
from matplotlib.patches import Ellipse, Rectangle, ConnectionPatch
from matplotlib.lines import Line2D
from matplotlib.legend_handler import HandlerTuple
import contextlib
plt.rc("figure", dpi=300)
@cwindolf
cwindolf / inline_labels.py
Last active December 6, 2022 22:59
Inline {x,y}axis labels in Matplotlib
# https://stackoverflow.com/a/74706214/3979938
from matplotlib.transforms import offset_copy
def inline_xlabel(ax, label):
t = offset_copy(
ax.transAxes,
y=-(ax.xaxis.get_tick_padding() + ax.xaxis.get_tick_space()),
fig=fig,
units='points'
)
@cwindolf
cwindolf / normxcorr1d.py
Last active February 3, 2023 16:20
1D optionally normalized, optionally weighted, optionally centered cross-correlation in PyTorch (+ SciPy fallback), with API like F.conv1d
try:
import torch
import torch.nn.functional as F
HAVE_TORCH = True
except ImportError:
HAVE_TORCH = False
def normxcorr1d(
template,
x,
def regline(x, y, ax=None, **kwargs):
b = ((x - x.mean()) * (y - y.mean())).sum() / np.square(x - x.mean()).sum()
a = y.mean() - b * x.mean()
x0, x1 = ax.get_xlim()
r = np.corrcoef(x, y)[0, 1]
ax.plot([x0, x1], [a + b * x0, a + b * x1], lw=1)
ax.text(
0.1,
0.9,
f"$\\rho={r:.2f}$",
def tukey_scatter(x, y, iqrs=1.5, ax=None, **kwargs):
ax = ax or plt.gca()
x_25, x_75 = np.percentile(x, [25, 75])
x_iqr = x_75 - x_25
y_25, y_75 = np.percentile(x, [25, 75])
y_iqr = y_75 - y_25
inliers = np.flatnonzero(
(x_25 - iqrs * x_iqr < x)
& (x < x_75 + iqrs * x_iqr)
& (y_25 - iqrs * y_iqr < y)
@cwindolf
cwindolf / cmdstanpy_helpers.py
Created January 25, 2022 21:30
CmdStanPy helpers
from pathlib import Path
import cmdstanpy
import ujson
def stanc(name, code, workdir=".stan"):
Path(workdir).mkdir(exist_ok=True)
path = Path(workdir) / f"{name}.stan"
with open(path, "w") as f:
f.write(code)
model = cmdstanpy.CmdStanModel(stan_file=path, stanc_options={'warn-pedantic': True})