|
| 1 | +import sys |
| 2 | + |
| 3 | +import matplotlib.pyplot as plt |
| 4 | + |
| 5 | +sys.path.append("../../figures") |
| 6 | + |
| 7 | + |
| 8 | +def plot_tonotopy(bin_labels, values, names, expression_eff_list): |
| 9 | + from util import prism_style, prism_cleanup_axes |
| 10 | + |
| 11 | + color_dict = {"O1": "#9C5027", "O2": "#67279C"} |
| 12 | + |
| 13 | + prism_style() |
| 14 | + label_size = 20 |
| 15 | + tick_label_size = 14 |
| 16 | + |
| 17 | + # result = pd.DataFrame(result) |
| 18 | + # bin_labels = pd.unique(result["octave_band"]) |
| 19 | + # band_to_x = {band: i for i, band in enumerate(bin_labels)} |
| 20 | + # result["x_pos"] = result["octave_band"].map(band_to_x) |
| 21 | + |
| 22 | + fig, ax = plt.subplots(figsize=(8, 4)) |
| 23 | + |
| 24 | + offset = 0.08 |
| 25 | + for num in range(len(names)): |
| 26 | + |
| 27 | + name = names[num] |
| 28 | + expr_vals = values[num] |
| 29 | + |
| 30 | + x_positions = range(len(bin_labels)) |
| 31 | + x_positions = [x - len(bin_labels) // 2 * offset + offset * num for x in x_positions] |
| 32 | + |
| 33 | + x_positions = [pos for i, pos in enumerate(x_positions) if expr_vals[i] is not None] |
| 34 | + expr_vals = [val for val in expr_vals if val is not None] |
| 35 | + assert len(x_positions) == len(expr_vals) |
| 36 | + |
| 37 | + ax.scatter(x_positions, expr_vals, marker="o", label=name, s=80, alpha=1, color=color_dict[name]) |
| 38 | + |
| 39 | + xlim_left, xlim_right = ax.get_xlim() |
| 40 | + y_offset = [0.01, -0.04] |
| 41 | + x_offset = 0.5 |
| 42 | + plt.xlim(xlim_left, xlim_right) |
| 43 | + for num, key in enumerate(color_dict.keys()): |
| 44 | + color = color_dict[key] |
| 45 | + expression_eff = expression_eff_list[num] |
| 46 | + |
| 47 | + ax.text(xlim_left + x_offset, expression_eff + y_offset[num], "mean", |
| 48 | + color=color, fontsize=tick_label_size, ha="center") |
| 49 | + trend_r, = ax.plot( |
| 50 | + [xlim_left, xlim_right], |
| 51 | + [expression_eff, expression_eff], |
| 52 | + linestyle="dashed", |
| 53 | + color=color, |
| 54 | + alpha=0.7, |
| 55 | + zorder=0 |
| 56 | + ) |
| 57 | + |
| 58 | + ax.set_xticks(range(len(bin_labels))) |
| 59 | + ax.set_xticklabels(bin_labels) |
| 60 | + ax.set_xlabel("Octave band [kHz]", fontsize=label_size) |
| 61 | + |
| 62 | + ax.set_ylabel("Expression efficiency") |
| 63 | + plt.tight_layout() |
| 64 | + prism_cleanup_axes(ax) |
| 65 | + |
| 66 | + plt.show() |
| 67 | + |
| 68 | + |
| 69 | +def main(): |
| 70 | + frequencies = ["4-8", "8-12", "12-16", "16-24", "24-32"] |
| 71 | + |
| 72 | + n_ihcs_23R = [51, 107, 77, 105, None] |
| 73 | + n_pos_23R = [15, 36, 24, 29, None] |
| 74 | + assert len(n_ihcs_23R) == len(n_pos_23R) |
| 75 | + assert len(n_ihcs_23R) == len(frequencies) |
| 76 | + |
| 77 | + n_ihcs_25R = [None, 103, 71, 102, 70] |
| 78 | + n_pos_25R = [None, 24, 21, 28, 2] |
| 79 | + assert len(n_ihcs_25R) == len(n_pos_25R) |
| 80 | + assert len(n_ihcs_25R) == len(frequencies) |
| 81 | + |
| 82 | + total_23R = sum(n for n in n_ihcs_23R if n is not None) |
| 83 | + pos_23R = sum(n for n in n_pos_23R if n is not None) |
| 84 | + eff_23R = float(pos_23R) / total_23R |
| 85 | + print("N-IHCs 23R:", total_23R) |
| 86 | + print("Expr. Eff.:", eff_23R) |
| 87 | + print() |
| 88 | + |
| 89 | + total_25R = sum(n for n in n_ihcs_25R if n is not None) |
| 90 | + pos_25R = sum(n for n in n_pos_25R if n is not None) |
| 91 | + eff_25R = float(pos_25R) / total_25R |
| 92 | + print("N-IHCs 25R:", total_25R) |
| 93 | + print("Expr. Eff.:", eff_25R) |
| 94 | + |
| 95 | + expr_23R = [None if n is None else float(pos) / n |
| 96 | + for pos, n in zip(n_pos_23R, n_ihcs_23R)] |
| 97 | + expr_25R = [None if n is None else float(pos) / n |
| 98 | + for pos, n in zip(n_pos_25R, n_ihcs_25R)] |
| 99 | + plot_tonotopy( |
| 100 | + frequencies, |
| 101 | + values=[expr_23R, expr_25R], |
| 102 | + names=["O1", "O2"], |
| 103 | + expression_eff_list=[eff_23R, eff_25R] |
| 104 | + ) |
| 105 | + |
| 106 | + |
| 107 | +if __name__ == "__main__": |
| 108 | + main() |
0 commit comments