pyCoReGraph 0.0.1a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
coregraph/__init__.py ADDED
@@ -0,0 +1,57 @@
1
+ __version__ = "0.0.1a1"
2
+
3
+ # Models
4
+ from coregraph.models import (
5
+ CoReGraph_Cors,
6
+ CoReGraph_Graphics,
7
+ CoReGraph,
8
+ StarGraph,
9
+ )
10
+
11
+ # Analysis
12
+ from coregraph.analysis.queries import (
13
+ get_correlation,
14
+ get_all_correlations,
15
+ get_mac,
16
+ get_mac_results,
17
+ get_regulated_genes,
18
+ get_regulator_genes,
19
+ )
20
+
21
+ # Graphics
22
+ from coregraph.graphics.plots import (
23
+ plot_expression,
24
+ plot_correlations,
25
+ )
26
+
27
+ from coregraph.graphics.animations import (
28
+ animate_correlations,
29
+ )
30
+
31
+ from coregraph.graphics.network import (
32
+ animate_network,
33
+ )
34
+
35
+ from coregraph.analysis.subset import (
36
+ starry,
37
+ subset_coregraph,
38
+ )
39
+
40
+ __all__ = [
41
+ "CoReGraph",
42
+ "CoReGraph_Cors",
43
+ "CoReGraph_Graphics",
44
+ "StarGraph",
45
+ "get_correlation",
46
+ "get_all_correlations",
47
+ "get_mac",
48
+ "get_mac_results",
49
+ "get_regulated_genes",
50
+ "get_regulator_genes",
51
+ "plot_expression",
52
+ "plot_correlations",
53
+ "animate_correlations",
54
+ "animate_network",
55
+ "starry",
56
+ "subset_coregraph"
57
+ ]
@@ -0,0 +1,45 @@
1
+ from .correlations import (
2
+ _calculate_all_cors,
3
+ _calculate_LEAP_cors,
4
+ _calculate_star_cors,
5
+ )
6
+
7
+ from .bins import (
8
+ _calculate_bins,
9
+ )
10
+
11
+ from .fdr import (
12
+ _calculate_FDR,
13
+ _calculate_star_FDR
14
+ )
15
+
16
+ from .queries import (
17
+ get_correlation,
18
+ get_all_correlations,
19
+ get_mac,
20
+ get_mac_results,
21
+ get_regulated_genes,
22
+ get_regulator_genes,
23
+ )
24
+
25
+ __all__ = [
26
+ # Correlations
27
+ "_calculate_all_cors",
28
+ "_calculate_LEAP_cors",
29
+ "_calculate_star_cors",
30
+
31
+ # FDR
32
+ "_calculate_FDR",
33
+ "_calculate_star_FDR",
34
+
35
+ # Bins
36
+ "_calculate_bins",
37
+
38
+ # Queries
39
+ "get_correlation",
40
+ "get_all_correlations",
41
+ "get_mac",
42
+ "get_mac_results",
43
+ "get_regulated_genes",
44
+ "get_regulator_genes",
45
+ ]
@@ -0,0 +1,23 @@
1
+ ## BINS ##
2
+
3
+ import numpy as np
4
+
5
+
6
+ def _calculate_bins(data, pseudotime, n_bins):
7
+ '''Discretize pseudotime expression in bins'''
8
+
9
+ bin_range = (pseudotime.max() - pseudotime.min())/n_bins
10
+ bin_seq = pseudotime.min() + np.arange(1,n_bins)*bin_range
11
+ bins = (np.digitize(pseudotime, bin_seq)*bin_range)+(bin_range/2)
12
+
13
+ mean_res = np.empty((data.shape[0], n_bins), dtype=np.float64)
14
+ std_res = np.empty((data.shape[0], n_bins), dtype=np.float64)
15
+ for i, b in enumerate(np.unique(bins)):
16
+ mean_res[:,i] = np.mean(data[:,bins==b], axis=1)
17
+ std_res[:,i] = np.mean(data[:,bins==b], axis=1)
18
+
19
+ mean = mean_res
20
+ std = std_res
21
+ scaled = mean/np.max(mean, axis=1)[:, None]
22
+
23
+ return bins, mean, std, scaled
@@ -0,0 +1,110 @@
1
+ ## CORRELATIONS ##
2
+
3
+ import numpy as np
4
+
5
+
6
+ def _calculate_all_cors(data, window, i, tensor, reflag, MAC, LAG_id, LAG, LAG_means, dim3_start, step=1, num_format=np.array([1,15]), dtype=np.float64):
7
+ '''Calculate all lagged correlations for a unique given reference i'''
8
+ dim3 = dim3_start
9
+ n_genes, n_cells = data.shape
10
+
11
+ data_ref = data[:,i:window+i]
12
+ mean_ref = np.mean(data_ref, axis=1)
13
+ cent_ref = data_ref.T - mean_ref
14
+ rowsumx_ref = np.sum(cent_ref, axis=0).reshape(1, -1)
15
+ rowsumx2_ref = np.sum(np.square(cent_ref), axis=0).reshape(1, -1)
16
+
17
+ for j in range(i, n_cells-window+1, step):
18
+ data_lag = data[:,j:window+j]
19
+ mean_lag = np.mean(data_lag, axis=1)
20
+ cent_lag = data_lag.T - mean_lag
21
+ rowsumx_lag = np.sum(cent_lag, axis=0).reshape(1, -1)
22
+ rowsumx2_lag = np.sum(np.square(cent_lag), axis=0).reshape(1, -1)
23
+
24
+ Cor = (np.dot(cent_ref.T, cent_lag) - (1 / window) * np.dot(rowsumx_ref.T, rowsumx_lag)) / \
25
+ np.dot(np.sqrt(rowsumx2_ref - rowsumx_ref**2 / window).T, np.sqrt(rowsumx2_lag - rowsumx_lag**2 / window))
26
+
27
+ np.fill_diagonal(Cor, 1)
28
+ Cor = np.round(np.nan_to_num(Cor, nan=0)*num_format[0], num_format[1])
29
+ Cor = Cor.astype(dtype)
30
+ tensor[:,:,dim3] = Cor
31
+ LAG_means[dim3] = mean_lag
32
+ reflag[dim3,0] = i
33
+ reflag[dim3,1] = j
34
+
35
+ # Update MAC
36
+ ind = np.abs(MAC) < np.abs(Cor)
37
+ MAC[ind] = Cor[ind]
38
+ LAG[ind] = j-i
39
+ LAG_id[0][ind] = i
40
+ LAG_id[1][ind] = j
41
+ #
42
+ dim3 += 1
43
+
44
+ return dim3, MAC, LAG_id, LAG, LAG_means
45
+
46
+ def _calculate_LEAP_cors(data, window, i=0, step=1, num_format=np.array([1,15]), dtype=np.float64):
47
+ '''Calculate all lagged correlations for a unique given reference i using LEAP traditional algorithm'''
48
+ n_genes, n_cells = data.shape
49
+ MAC = np.zeros((n_genes, n_genes))
50
+ LAG = np.zeros((n_genes, n_genes))
51
+
52
+ data_ref = data[:,i:window+i]
53
+ mean_ref = np.mean(data_ref, axis=1)
54
+ cent_ref = data_ref.T - mean_ref
55
+ rowsumx_ref = np.sum(cent_ref, axis=0).reshape(1, -1)
56
+ rowsumx2_ref = np.sum(np.square(cent_ref), axis=0).reshape(1, -1)
57
+
58
+ for j in range(i, n_cells - window, step):
59
+ data_lag = data[:,j:window+j]
60
+ mean_lag = np.mean(data_lag, axis=1)
61
+ cent_lag = data_lag.T - mean_lag
62
+ rowsumx_lag = np.sum(cent_lag, axis=0).reshape(1, -1)
63
+ rowsumx2_lag = np.sum(np.square(cent_lag), axis=0).reshape(1, -1)
64
+
65
+ Cor = np.dot(cent_ref.T, cent_lag) - (1 / window) * np.dot(rowsumx_ref.T, rowsumx_lag) / \
66
+ np.dot(np.sqrt(rowsumx2_ref - rowsumx_ref**2 / window).T, np.sqrt(rowsumx2_lag - rowsumx_lag**2 / window))
67
+
68
+ np.fill_diagonal(Cor, 1)
69
+ Cor = np.round(np.nan_to_num(Cor, nan=0)*num_format[0], num_format[1])
70
+ Cor = Cor.astype(dtype)
71
+ # Update MAC
72
+ ind = np.where(np.abs(MAC) > np.abs(Cor))
73
+ LAG[ind] = j - i
74
+ MAC[ind] = Cor[ind]
75
+
76
+ return MAC, LAG
77
+
78
+
79
+ def _calculate_star_cors(data, target_row, MAC, window, i, step=1, num_format=np.array([1,15]), dtype=np.float64):
80
+ '''Calculate all lagged correlations for a unique given reference i using a single reference row against all rows.'''
81
+
82
+ n_genes, n_cells = data.shape
83
+
84
+ # Take reference row only
85
+ data_ref = data[target_row, i:window+i]
86
+ mean_ref = np.mean(data_ref)
87
+ cent_ref = data_ref - mean_ref
88
+
89
+ sum_ref = np.sum(cent_ref)
90
+ sum_ref2 = np.sum(np.square(cent_ref), axis=0)
91
+
92
+ for j in range(i, n_cells - window, step):
93
+ data_lag = data[:, j:window+j]
94
+ mean_lag = np.mean(data_lag, axis=1)
95
+ cent_lag = data_lag - mean_lag[:, None]
96
+
97
+ rowsumx_lag = np.sum(cent_lag, axis=1)
98
+ rowsumx2_lag = np.sum(cent_lag * cent_lag, axis=1)
99
+ cross = np.dot(cent_lag, cent_ref)
100
+
101
+ Cor = (cross - (rowsumx_lag * sum_ref) / window) / \
102
+ (np.sqrt(rowsumx2_lag - (rowsumx_lag * rowsumx_lag) / window) * np.sqrt(sum_ref2 - (sum_ref * sum_ref) / window))
103
+
104
+ Cor = np.round(np.nan_to_num(Cor, nan=0)*num_format[0], num_format[1])
105
+ Cor = Cor.astype(dtype)
106
+
107
+ ind = np.where(np.abs(MAC) < np.abs(Cor))
108
+ MAC[ind] = Cor[ind]
109
+
110
+ return MAC
@@ -0,0 +1,100 @@
1
+ ## FDR ##
2
+
3
+ import numpy as np
4
+
5
+ from coregraph.analysis.correlations import (_calculate_LEAP_cors, _calculate_star_cors)
6
+
7
+
8
+ def _calculate_FDR(data, MAC, window, n_perms = 100, FDR_cutoffs = 101, step=1, num_format=np.array([1,15]), dtype=np.float64):
9
+ '''Calculate False Discovery Rate by permutations'''
10
+
11
+ MAC_true = np.absolute(MAC.copy())
12
+ samp_size = np.minimum(100, data.shape[0])
13
+ MACs_perm = np.zeros((n_perms, samp_size, samp_size))
14
+ np.fill_diagonal(MAC_true, -1)
15
+
16
+ # simplified MAC_counter function
17
+ for n in range(0, n_perms):
18
+ np.random.seed(n)
19
+ data_perm = data[0:samp_size,:].copy()
20
+ inds = np.random.choice(data.shape[0], size=samp_size, replace=False)
21
+
22
+ for z in range(0, samp_size):
23
+ data_perm[z,:] = np.random.permutation(data[inds[z],:])
24
+
25
+ MAC_p, _ = _calculate_LEAP_cors(data_perm, window, 0, step, num_format, dtype)
26
+ MAC_p = np.absolute(MAC_p)
27
+ np.fill_diagonal(MAC_p, -1)
28
+ MACs_perm[n] = MAC_p
29
+
30
+ # Calculate FDR
31
+ cors = np.linspace(0, 1, FDR_cutoffs)
32
+ num_cors_perm = np.full(FDR_cutoffs, 0)
33
+ MACs_observed = np.full(FDR_cutoffs, 0)
34
+
35
+ for r in range(0, FDR_cutoffs):
36
+ num_cors_perm[r] += np.sum(MACs_perm >= cors[r])
37
+ MACs_observed[r] += np.sum(MAC_true >= cors[r])
38
+
39
+ perm_size = samp_size*samp_size-samp_size
40
+ obs_size = MAC_true.shape[0]*MAC_true.shape[1]-MAC_true.shape[0]
41
+ MACs_ave_perm = num_cors_perm/n_perms*(obs_size/perm_size)
42
+ fdr = np.full(FDR_cutoffs, np.nan)
43
+
44
+ for s in range(0,FDR_cutoffs):
45
+ if MACs_observed[s] == 0:
46
+ fdr[s] = 0
47
+ else:
48
+ fdr[s] = MACs_ave_perm[s]/MACs_observed[s]
49
+
50
+ results = np.column_stack((cors, MACs_observed, MACs_ave_perm, fdr))
51
+
52
+ return results[::-1]
53
+
54
+ def _calculate_star_FDR(data, target_row, MAC, window, n_perms = 100, FDR_cutoffs = 101, step=1, num_format=np.array([1,15]), dtype=np.float64):
55
+ '''Calculate False Discovery Rate by permutations for a single reference row against all rows.'''
56
+
57
+ MAC_true = np.absolute(MAC.copy())
58
+ samp_size = np.minimum(100, data.shape[0])
59
+ MACs_perm = np.zeros((n_perms, samp_size))
60
+ MAC_true[target_row] = -1
61
+
62
+ # simplified MAC_counter function
63
+ for n in range(0, n_perms):
64
+ np.random.seed(n)
65
+ ref_perm = data[target_row,:].copy()
66
+ data_perm = data[0:samp_size-1,:].copy()
67
+ data_perm = np.concatenate((ref_perm.reshape((1,-1)), data_perm))
68
+ inds = np.random.choice(data.shape[0], size=samp_size, replace=False)
69
+
70
+ for z in range(0, samp_size):
71
+ data_perm[z,:] = np.random.permutation(data[inds[z],:])
72
+
73
+ MAC_p = _calculate_star_cors(data_perm, 0, np.zeros((samp_size), dtype=dtype), window, i=0, step=step, num_format=num_format, dtype=dtype)
74
+ MAC_p = np.absolute(MAC_p)
75
+ MAC_p[0] = -1
76
+ MACs_perm[n] = MAC_p
77
+
78
+ ### Calculate FDR ###
79
+ cors = np.linspace(0, 1, FDR_cutoffs)
80
+ num_cors_perm = np.full(FDR_cutoffs, 0)
81
+ MACs_observed = np.full(FDR_cutoffs, 0)
82
+
83
+ for r in range(0, FDR_cutoffs):
84
+ num_cors_perm[r] += np.sum(MACs_perm >= cors[r])
85
+ MACs_observed[r] += np.sum(MAC_true >= cors[r])
86
+
87
+ perm_size = samp_size-1
88
+ obs_size = MAC_true.shape[0]-1
89
+ MACs_ave_perm = num_cors_perm/n_perms*(obs_size/perm_size)
90
+ fdr = np.full(FDR_cutoffs, np.nan)
91
+
92
+ for s in range(0,FDR_cutoffs):
93
+ if MACs_observed[s] == 0:
94
+ fdr[s] = 0
95
+ else:
96
+ fdr[s] = MACs_ave_perm[s]/MACs_observed[s]
97
+
98
+ results = np.column_stack((cors, MACs_observed, MACs_ave_perm, fdr))
99
+
100
+ return results[::-1]
@@ -0,0 +1,118 @@
1
+ ## QUERIES ##
2
+
3
+ from __future__ import annotations
4
+
5
+ import numpy as np
6
+ import pandas as pd
7
+
8
+ from coregraph.utils.decorators import (requires_cors, requires_FDR)
9
+
10
+
11
+ @requires_cors
12
+ def get_correlation(C: CoReGraph, regulator: str, target: str, ref_lag: tuple[int, int]) -> float:
13
+ '''Get correlation value between two genes at a specific (reference, lag) window pair.'''
14
+ ref, lag = ref_lag
15
+
16
+ if (ref % C.cors.step != 0) or (lag % C.cors.step != 0):
17
+ raise ValueError(f"ref_lag must be multiples of step={C.cors.step}")
18
+
19
+ reg_idx = C.gene_to_idx[regulator]
20
+ tar_idx = C.gene_to_idx[target]
21
+
22
+ if ref <= lag:
23
+ tensor_i = reg_idx
24
+ tensor_j = tar_idx
25
+ search_ref = ref
26
+ search_lag = lag
27
+ else:
28
+ tensor_i = tar_idx
29
+ tensor_j = reg_idx
30
+ search_ref = lag
31
+ search_lag = ref
32
+
33
+ dim3 = np.argwhere((C.cors.reflag[:, 0] == search_ref) & (C.cors.reflag[:, 1] == search_lag))[0][0]
34
+
35
+ value = (C.cors.tensor[tensor_i, tensor_j, dim3] / C.cors.num_format[0])
36
+
37
+ return float(value)
38
+
39
+
40
+ @requires_cors
41
+ def get_all_correlations(C: CoReGraph, regulator: str, target: str, ref: int) -> np.ndarray:
42
+ '''Get all lagged correlations between two genes for a fixed reference window.'''
43
+ if (ref % C.cors.step != 0) :
44
+ raise ValueError(f"ref must be a multiple of step={C.cors.step}")
45
+
46
+ correlations = np.empty(C.cors.n_steps, dtype=C.cors.dtype)
47
+
48
+ for i in range(C.cors.n_steps):
49
+ lag = i * C.cors.step
50
+ correlations[i] = get_correlation(C,regulator,target,(ref, lag))
51
+
52
+ return correlations
53
+
54
+
55
+ @requires_cors
56
+ def get_mac(C: CoReGraph, regulator: str, target: str) -> dict:
57
+ '''Get maximal absolute correlation (MAC) and corresponding reference/lag pair for two genes.'''
58
+ reg_idx = C.gene_to_idx[regulator]
59
+ tar_idx = C.gene_to_idx[target]
60
+
61
+ return {
62
+ "ref": int(C.cors.LAG_id[0, reg_idx, tar_idx]),
63
+ "lag": int(C.cors.LAG_id[1, reg_idx, tar_idx]),
64
+ "cor": float(C.cors.MAC[reg_idx, tar_idx] / C.cors.num_format[0])
65
+ }
66
+
67
+
68
+ @requires_cors
69
+ def get_mac_results(C: CoReGraph) -> tuple[pd.DataFrame, pd.DataFrame]:
70
+ '''Get MAC and LAG matrices.'''
71
+ mac_df = pd.DataFrame(C.cors.MAC / C.cors.num_format[0], index=C.gene_id, columns=C.gene_id)
72
+ lag_df = pd.DataFrame(C.cors.LAG, index=C.gene_id, columns=C.gene_id)
73
+
74
+ return mac_df, lag_df
75
+
76
+
77
+ @requires_cors
78
+ @requires_FDR
79
+ def get_regulated_genes(C: CoReGraph, regulator: str, cor_threshold: float=0.0) -> pd.DataFrame:
80
+ '''Get genes regulated by a regulator gene.'''
81
+ reg_idx = C.gene_to_idx[regulator]
82
+
83
+ values = (C.cors.MAC[reg_idx, :] / C.cors.num_format[0])
84
+
85
+ df = pd.DataFrame({
86
+ "gene": C.gene_id,
87
+ "correlation": values,
88
+ "lag": C.cors.LAG[reg_idx, :]
89
+ })
90
+
91
+ df = df[np.abs(df["correlation"]) > cor_threshold]
92
+
93
+ df = df.sort_values(by="correlation", key=np.abs, ascending=False)
94
+
95
+ return df.set_index("gene")
96
+
97
+
98
+ @requires_cors
99
+ @requires_FDR
100
+ def get_regulator_genes(C: CoReGraph, target: str, cor_threshold: float=0.0) -> pd.DataFrame:
101
+ '''Get genes regulated by a regulator gene.'''
102
+ tar_idx = C.gene_to_idx[target]
103
+
104
+ values = (C.cors.MAC[:, tar_idx] / C.cors.num_format[0])
105
+
106
+ df = pd.DataFrame({
107
+ "gene": C.gene_id,
108
+ "correlation": values,
109
+ "lag": C.cors.LAG[:, tar_idx]
110
+ })
111
+
112
+ df = df[np.abs(df["correlation"]) > cor_threshold]
113
+
114
+ df = df.sort_values(by="correlation", key=np.abs, ascending=False)
115
+
116
+ return df.set_index("gene")
117
+
118
+
@@ -0,0 +1,64 @@
1
+ ## REDUCTIONS ##
2
+
3
+ import numpy as np
4
+ import pandas as pd
5
+
6
+ from tqdm import tqdm
7
+
8
+ from coregraph.models.coregraph import CoReGraph
9
+ from coregraph.models.stargraph import StarGraph
10
+
11
+ from coregraph.analysis.correlations import _calculate_star_cors
12
+ from coregraph.analysis.fdr import _calculate_star_FDR
13
+ from coregraph.utils.validation import _solve_step
14
+
15
+
16
+ def starry(x, central_gene, window, FDR_thr=0.05, n_perms=100, FDR_cutoffs=501, step=None, n_steps=None, verbose=False):
17
+ '''Wrapped function to estimate starry gene regulatory network centered on a given gene'''
18
+ n_genes, n_cells = x.data.shape
19
+ target_row = x.gene_id.index(central_gene)
20
+ step, n_steps = _solve_step(step, n_steps, window, n_cells)
21
+
22
+ ## Calculate MAC ##
23
+ MAC = np.zeros((n_genes), dtype=np.float64)
24
+
25
+ np.seterr(divide='ignore', invalid='ignore')
26
+ iterator = tqdm(range(0, n_cells-window+1, step), desc="Calculating Correlations", disable=not verbose)
27
+ for i in iterator:
28
+ MAC = _calculate_star_cors(x.data, target_row, MAC, window, i, step)
29
+
30
+ ## Calculate FDR ##
31
+ FDR = _calculate_star_FDR(x.data, target_row, MAC, window, n_perms, FDR_cutoffs, step)
32
+ FDR = pd.DataFrame(FDR)
33
+ FDR.columns = ["cors", "MACs_observed", "MACs_ave_perm", "FDR"]
34
+ FDR[["MACs_observed"]] = FDR[["MACs_observed"]].astype(int)
35
+
36
+ cor_thr = min(FDR['cors'][FDR['FDR'] < FDR_thr])
37
+ MAC = pd.DataFrame(MAC, index=x.gene_id, columns=['MAC'])
38
+ MAC = MAC.sort_values(by='MAC', key=abs, ascending=False)
39
+
40
+ ## Create a new object and fill in it ##
41
+ star = StarGraph()
42
+ star.central_gene = central_gene
43
+ star.window = window
44
+ star.step = step
45
+ star.n_steps = n_steps
46
+ star.MAC = MAC
47
+ star.FDR = FDR
48
+ star.set_FDR_threshold(FDR_thr)
49
+
50
+ return star
51
+
52
+
53
+ def subset_coregraph(C: CoReGraph, gene_list: list[str]) -> CoReGraph:
54
+ id_dict = {}
55
+ for i, b in enumerate(C.gene_id):
56
+ id_dict[b] = i
57
+
58
+ shared_id = [id_dict[g] for g in gene_list]
59
+ shared_id.sort()
60
+ subdata = C.data[shared_id,:]
61
+ subid = [C.gene_id[g] for g in shared_id]
62
+
63
+ subobject = CoReGraph(subdata, C.pseudotime, subid, C.cell_id)
64
+ return subobject
@@ -0,0 +1,33 @@
1
+ from .colors import (
2
+ ColorBlind,
3
+ )
4
+
5
+ from .plots import (
6
+ plot_expression,
7
+ plot_correlations,
8
+ )
9
+
10
+ from .animations import (
11
+ animate_correlations,
12
+ )
13
+
14
+ from .network import (
15
+ animate_network,
16
+ )
17
+
18
+ __all__ = [
19
+ # Colors
20
+ "ColorBlind",
21
+
22
+ # Plots
23
+ "plot_expression",
24
+ "plot_correlations",
25
+
26
+ # Animations
27
+ "animate_correlations",
28
+
29
+ # Network
30
+ "animate_network",
31
+ ]
32
+
33
+
@@ -0,0 +1,56 @@
1
+ ## ANIMATIONS ##
2
+
3
+ from __future__ import annotations
4
+
5
+ import numpy as np
6
+ import matplotlib.pyplot as plt
7
+ import matplotlib.patches as patches
8
+
9
+ from matplotlib.animation import FuncAnimation
10
+
11
+ from coregraph.graphics.colors import ColorBlind
12
+ from coregraph.analysis.queries import (get_all_correlations)
13
+ from coregraph.utils.decorators import (requires_cors, requires_bins)
14
+
15
+
16
+ @requires_bins
17
+ @requires_cors
18
+ def animate_correlations(C: CoReGraph, regulator: str, target: str, ref: int, scaled: bool=False, decimals: int=15, color: list=(ColorBlind[0], ColorBlind[3]), linewidth: float=1, figsize: tuple=(8,4)):
19
+ '''Animate lagged correlations.'''
20
+ if C.graphics.n_bins is None:
21
+ raise ValueError("Bins have not been calculated.")
22
+
23
+ values = (C.graphics.scaled if scaled else C.graphics.mean)
24
+ reg_idx = C.gene_to_idx[regulator]
25
+ tar_idx = C.gene_to_idx[target]
26
+ y_max = np.max([values[reg_idx, :], values[tar_idx, :]]) * 1.1
27
+ all_cors = get_all_correlations(C, regulator, target, ref)
28
+ all_cors_norm = (all_cors / np.max(np.abs(all_cors)))
29
+
30
+ fig, ax = plt.subplots(1, 2, figsize=figsize, width_ratios=[25, 1],)
31
+ x = np.unique(C.graphics.bin_id)
32
+
33
+ # Regulator and target lines
34
+ ax[0].plot(x, values[reg_idx, :], color=color[0])
35
+ ax[0].plot(x, values[tar_idx, :], color=color[1],)
36
+
37
+ fixed_rect = ax[0].add_patch(patches.Rectangle((ref, 0), C.cors.window, y_max, facecolor=color[0], alpha=0.1,))
38
+ moving_rect = ax[0].add_patch(patches.Rectangle((0, 0), C.cors.window, y_max, facecolor=color[1], alpha=0.1,))
39
+
40
+ cor_text = ax[0].annotate("", (C.n_cells * 0.01, y_max * 0.8))
41
+ lag_text = ax[0].annotate("", (C.n_cells * 0.01, y_max * 0.9))
42
+
43
+ def update(frame):
44
+ lag = frame * C.cors.step
45
+ moving_rect.set_x(lag)
46
+ cor = all_cors[frame]
47
+ cor_text.set_text(f"cor = {np.round(cor, decimals)}")
48
+ lag_text.set_text(f"lag = {lag}")
49
+
50
+ return (moving_rect, cor_text, lag_text)
51
+
52
+ ani = FuncAnimation(fig, update, frames=C.cors.n_steps, blit=True)
53
+ #HTML(ani.to_jshtml())
54
+ return ani
55
+
56
+
@@ -0,0 +1,9 @@
1
+ ## COLORS ##
2
+
3
+ # Colorblind friendly set of colors
4
+ Blues = ['#016BA0','#5F9ED1','#A1C8EB','#3399FF', '#006ddb','#330066']
5
+ YReds = ['#FF0000','#FF9933','#F0E442','#ffff6d','#FF7070']
6
+ Greys = ['#131313','#555555','#809099','#CFCFCF','#F2F4F4']
7
+ Others = ['#FFBBAB']
8
+
9
+ ColorBlind = [Blues[0], YReds[0], Blues[1], YReds[1], Blues[2], YReds[2], Blues[3], YReds[3], Blues[4], YReds[4], Blues[5], Others[0], Greys[0], Greys[1], Greys[2], Greys[3], Greys[4]]