Skip to content

Commit bb4364e

Browse files
Add and update some plots
1 parent cadf297 commit bb4364e

File tree

3 files changed

+286
-35
lines changed

3 files changed

+286
-35
lines changed

scripts/figures/plot_fig3.py

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,31 @@ def fig_03c_octave(save_path, plot=False):
145145
plt.close()
146146

147147

148+
def fig_03d(save_path, plot, print_stats=True):
149+
result_folder = "../measurements/subtype_analysis"
150+
files = glob(os.path.join(result_folder, "*.tsv"))
151+
152+
for ff in files:
153+
fname = os.path.basename(ff)
154+
cochlea = fname[:-len("_subtype_analysis.tsv")]
155+
table = pd.read_csv(ff, sep="\t")
156+
157+
subtype_table = table[[col for col in table.columns if col.startswith("is_")]]
158+
assert subtype_table.shape[1] == 2
159+
n_sgns = len(subtype_table)
160+
161+
if print_stats:
162+
print(cochlea)
163+
for col in subtype_table.columns:
164+
vals = table[col].values
165+
subtype = col[3:]
166+
n_subtype = vals.sum()
167+
print(subtype, ":", n_subtype, "/", n_sgns, f"({np.round(float(n_subtype) / n_sgns * 100, 2)} %)")
168+
169+
coexpr = np.logical_and(subtype_table.iloc[:, 0].values, subtype_table.iloc[:, 1].values)
170+
print("Co-expression:", coexpr.sum())
171+
172+
148173
def main():
149174
parser = argparse.ArgumentParser(description="Generate plots for Fig 3 of the cochlea paper.")
150175
parser.add_argument("--figure_dir", "-f", type=str, help="Output directory for plots.", default="./panels/fig3")
@@ -154,17 +179,18 @@ def main():
154179
os.makedirs(args.figure_dir, exist_ok=True)
155180

156181
# Panel A: Tonotopic mapping of IHCs (rendering in napari)
157-
fig_03a(save_path=os.path.join(args.figure_dir, "fig_03a.png"), plot=args.plot, plot_napari=False)
182+
# fig_03a(save_path=os.path.join(args.figure_dir, "fig_03a.png"), plot=args.plot, plot_napari=False)
158183

159184
# Panel B: Tonotopic mapping of SGNs (rendering in napari)
160-
fig_03b(save_path=os.path.join(args.figure_dir, "fig_03b.png"), plot=args.plot, plot_napari=False)
185+
# fig_03b(save_path=os.path.join(args.figure_dir, "fig_03b.png"), plot=args.plot, plot_napari=False)
161186

162187
# Panel C: Spatial distribution of synapses across the cochlea.
163188
# We have two options: running sum over the runlength or per octave band
164189
# fig_03c_rl(save_path=os.path.join(args.figure_dir, "fig_03c_runlength.png"), plot=args.plot)
165-
fig_03c_octave(save_path=os.path.join(args.figure_dir, "fig_03c_octave.png"), plot=args.plot)
190+
# fig_03c_octave(save_path=os.path.join(args.figure_dir, "fig_03c_octave.png"), plot=args.plot)
166191

167-
# TODO: Panel D: Spatial distribution of SGN sub-types.
192+
# Panel D: Spatial distribution of SGN sub-types.
193+
fig_03d(save_path=os.path.join(args.figure_dir, "fig_03d.png"), plot=args.plot)
168194

169195

170196
if __name__ == "__main__":

scripts/figures/plot_fig5.py

Lines changed: 102 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,114 @@
11
import argparse
2+
import json
23
import os
34

45
import numpy as np
56
import pandas as pd
67
import matplotlib.pyplot as plt
78

8-
from util import literature_reference_values
9+
from flamingo_tools.s3_utils import BUCKET_NAME, create_s3_target
10+
11+
from util import SYNAPSE_DIR_ROOT
12+
from plot_fig4 import get_chreef_data
913

1014
png_dpi = 300
1115

1216

1317
def _load_ribbon_synapse_counts():
18+
# TODO update the version!
1419
ihc_version = "ihc_counts_v4b"
15-
synapse_dir = f"/mnt/vast-nhr/projects/nim00007/data/moser/cochlea-lightsheet/predictions/synapses/{ihc_version}"
16-
tables = [entry.path for entry in os.scandir(synapse_dir) if "ihc_count_M_AMD" in entry.name]
17-
syn_counts = []
18-
for tab in tables:
19-
x = pd.read_csv(tab, sep="\t")
20-
syn_counts.extend(x["synapse_count"].values.tolist())
20+
table_path = os.path.join(SYNAPSE_DIR_ROOT, ihc_version, "ihc_count_M_AMD_OTOF1_L.tsv")
21+
x = pd.read_csv(table_path, sep="\t")
22+
syn_counts = x.synapse_count.values.tolist()
2123
return syn_counts
2224

2325

2426
def fig_05c(save_path, plot=False):
25-
"""Bar plot showing the distribution of synapse markers per IHC segmentation average over OTOF cochlea.
27+
"""Bar plot showing the IHC count and distribution of synapse markers per IHC segmentation over OTOF cochlea.
2628
"""
29+
# TODO update the alias.
30+
# For MOTOF1L
31+
alias = "M10L"
2732

2833
main_label_size = 20
2934
main_tick_size = 12
3035
htext_size = 10
3136

3237
ribbon_synapse_counts = _load_ribbon_synapse_counts()
3338

34-
fig, ax = plt.subplots(figsize=(8, 4))
39+
rows, columns = 1, 2
40+
fig, axes = plt.subplots(rows, columns, figsize=(columns*4, rows*4))
41+
42+
#
43+
# Create the plot for IHCs.
44+
#
45+
ihc_values = [len(ribbon_synapse_counts)]
46+
47+
ylim0 = 600
48+
ylim1 = 800
49+
y_ticks = [i for i in range(600, 800 + 1, 100)]
3550

51+
axes[0].set_ylabel("IHC count", fontsize=main_label_size)
52+
axes[0].set_yticks(y_ticks)
53+
axes[0].set_yticklabels(y_ticks, rotation=0, fontsize=main_tick_size)
54+
axes[0].set_ylim(ylim0, ylim1)
55+
56+
axes[0].boxplot(ihc_values)
57+
axes[0].set_xticklabels([alias], fontsize=main_label_size)
58+
59+
# Set the reference values for healthy cochleae
60+
xmin = 0.5
61+
xmax = 1.5
62+
ihc_reference_values = [712, 710, 721, 675] # MLR226L, MLR226R, MLR227L, MLR227R
63+
64+
ihc_value = np.mean(ihc_reference_values)
65+
ihc_std = np.std(ihc_reference_values)
66+
67+
upper_y = ihc_value + 1.96 * ihc_std
68+
lower_y = ihc_value - 1.96 * ihc_std
69+
70+
axes[0].hlines([lower_y, upper_y], xmin, xmax, colors=["C1" for _ in range(2)])
71+
axes[0].text(1, upper_y + 10, "healthy cochleae", color="C1", fontsize=main_tick_size, ha="center")
72+
axes[0].fill_between([xmin, xmax], lower_y, upper_y, color="C1", alpha=0.05, interpolate=True)
73+
74+
#
75+
# Create the plot for ribbon synapse distribution.
76+
#
3677
ylim0 = -1
3778
ylim1 = 24
3879
y_ticks = [i for i in range(0, 25, 5)]
3980

40-
ax.set_ylabel("Ribbon Syn. per IHC", fontsize=main_label_size)
41-
ax.set_yticks(y_ticks)
42-
ax.set_yticklabels(y_ticks, rotation=0, fontsize=main_tick_size)
43-
ax.set_ylim(ylim0, ylim1)
81+
axes[1].set_ylabel("Ribbon Syn. per IHC", fontsize=main_label_size)
82+
axes[1].set_yticks(y_ticks)
83+
axes[1].set_yticklabels(y_ticks, rotation=0, fontsize=main_tick_size)
84+
axes[1].set_ylim(ylim0, ylim1)
85+
86+
axes[1].boxplot(ribbon_synapse_counts)
87+
axes[1].set_xticklabels([alias], fontsize=main_label_size)
4488

45-
ax.boxplot(ribbon_synapse_counts)
46-
ax.set_xticklabels(["MOTOF1L"], fontsize=main_label_size)
89+
axes[1].yaxis.tick_right()
90+
axes[1].yaxis.set_ticks_position("right")
91+
axes[1].yaxis.set_label_position("right")
4792

48-
# set range of literature values
93+
# Set the reference values for healthy cochleae
4994
xmin = 0.5
5095
xmax = 1.5
51-
lower_y, upper_y = literature_reference_values("synapse")
52-
ax.set_xlim(xmin, xmax)
53-
ax.hlines([lower_y, upper_y], xmin, xmax)
54-
ax.text(1.25, upper_y + 0.01*ax.get_ylim()[1]-ax.get_ylim()[0], "literature",
55-
color="C0", fontsize=htext_size, ha="center")
56-
ax.fill_between([xmin, xmax], lower_y, upper_y, color="C0", alpha=0.05, interpolate=True)
96+
syn_reference_values = [14.1, 12.7, 13.8, 13.4] # MLR226L, MLR226R, MLR227L, MLR227R
5797

58-
ihc_values = [14.1, 12.7, 13.8, 13.4] # MLR226L, MLR226R, MLR227L, MLR227R
98+
syn_value = np.mean(syn_reference_values)
99+
syn_std = np.std(syn_reference_values)
59100

60-
ihc_value = np.mean(ihc_values)
61-
ihc_std = np.std(ihc_values)
62-
63-
upper_y = ihc_value + 1.96 * ihc_std
64-
lower_y = ihc_value - 1.96 * ihc_std
101+
upper_y = syn_value + 1.96 * syn_std
102+
lower_y = syn_value - 1.96 * syn_std
65103

66104
plt.hlines([lower_y, upper_y], xmin, xmax, colors=["C1" for _ in range(2)])
67-
plt.text(1.25, upper_y + 0.01*ax.get_ylim()[1]-ax.get_ylim()[0], "healthy cochleae (95% confidence interval)",
68-
color="C1", fontsize=htext_size, ha="center")
105+
plt.text(
106+
1.25, upper_y + 0.01*axes[1].get_ylim()[1]-axes[1].get_ylim()[0], "healthy cochleae",
107+
color="C1", fontsize=htext_size, ha="center"
108+
)
69109
plt.fill_between([xmin, xmax], lower_y, upper_y, color="C1", alpha=0.05, interpolate=True)
70110

111+
# Save and plot the figure.
71112
plt.tight_layout()
72113
plt.savefig(save_path, bbox_inches="tight", pad_inches=0.1, dpi=png_dpi)
73114

@@ -77,6 +118,33 @@ def fig_05c(save_path, plot=False):
77118
plt.close()
78119

79120

121+
# TODO
122+
def fig_05d(save_path, plot):
123+
if False:
124+
s3 = create_s3_target()
125+
126+
# Intensity distribution for OTOF
127+
cochlea = "M_AMD_OTOF1_L"
128+
content = s3.open(f"{BUCKET_NAME}/{cochlea}/dataset.json", mode="r", encoding="utf-8")
129+
info = json.loads(content.read())
130+
sources = info["sources"]
131+
132+
# Load the seg table and filter the compartments.
133+
source_name = "IHC_v4c"
134+
source = sources[source_name]["segmentation"]
135+
rel_path = source["tableData"]["tsv"]["relativePath"]
136+
table_content = s3.open(os.path.join(BUCKET_NAME, cochlea, rel_path, "default.tsv"), mode="rb")
137+
table = pd.read_csv(table_content, sep="\t")
138+
print(table)
139+
140+
# TODO would need the new intensity subtracted data here.
141+
# Reference: intensity distributions for ChReef
142+
chreef_data = get_chreef_data()
143+
for cochlea, tab in chreef_data.items():
144+
plt.hist(tab["median"])
145+
plt.show()
146+
147+
80148
def main():
81149
parser = argparse.ArgumentParser(description="Generate plots for Fig 5 of the cochlea paper.")
82150
parser.add_argument("--figure_dir", "-f", type=str, help="Output directory for plots.", default="./panels/fig5")
@@ -86,7 +154,10 @@ def main():
86154
os.makedirs(args.figure_dir, exist_ok=True)
87155

88156
# Panel C: Monitoring of the Syn / IHC loss
89-
fig_05c(save_path=os.path.join(args.figure_dir, "fig_05c"), plot=args.plot)
157+
# fig_05c(save_path=os.path.join(args.figure_dir, "fig_05c"), plot=args.plot)
158+
159+
# Panel D: Tonotopic mapping of the intensities.
160+
fig_05d(save_path=os.path.join(args.figure_dir, "fig_05d"), plot=args.plot)
90161

91162

92163
if __name__ == "__main__":

0 commit comments

Comments
 (0)