Skip to content

Commit c778950

Browse files
committed
use of np.digitize and implementation of slider for bins
1 parent 7106fcc commit c778950

File tree

2 files changed

+49
-30
lines changed

2 files changed

+49
-30
lines changed

model.py

+19-22
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ def calc_mutations_per_tree(self):
556556
mutations_per_tree[unique_values] = counts
557557
return mutations_per_tree
558558

559-
def compute_ancestor_spans_heatmap_data(self, win_x_size=1_000_000, win_y_size=500):
559+
def compute_ancestor_spans_heatmap_data(self, num_x_bins, num_y_bins):
560560
"""
561561
Calculates the average ancestor span in a genomic-time window
562562
"""
@@ -565,38 +565,35 @@ def compute_ancestor_spans_heatmap_data(self, win_x_size=1_000_000, win_y_size=5
565565
nodes_left = nodes_df.child_left
566566
nodes_right = nodes_df.child_right
567567
nodes_time = nodes_df.time
568-
ancestors_span = nodes_df.ancestors_span
569568

570-
num_x_wins = int(np.ceil(nodes_right.max() - nodes_left.min()) / win_x_size)
571-
num_y_wins = int(np.ceil(nodes_time.max() / win_y_size))
572-
heatmap_sums = np.zeros((num_x_wins, num_y_wins))
573-
heatmap_counts = np.zeros((num_x_wins, num_y_wins))
569+
x_bins = np.linspace(nodes_left.min(), nodes_right.max(), num_x_bins + 1)
570+
y_bins = np.linspace(0, nodes_time.max(), num_y_bins + 1)
571+
heatmap_counts = np.zeros((num_x_bins, num_y_bins))
572+
573+
x_starts = np.digitize(nodes_left, x_bins, right=True)
574+
x_ends = np.digitize(nodes_right, x_bins, right=True)
575+
y_starts = np.digitize(nodes_time, y_bins, right=True)
574576

575577
for u in range(len(nodes_left)):
576-
x_start = int(
577-
np.floor(nodes_left[u] / win_x_size)
578-
) # map the node span to the x-axis bins it overlaps
579-
x_end = int(np.floor(nodes_right[u] / win_x_size))
580-
y = max(0, int(np.floor(nodes_time[u] / win_y_size)) - 1)
581-
heatmap_sums[x_start:x_end, y] += min(ancestors_span[u], win_x_size)
582-
heatmap_counts[x_start:x_end, y] += 1
583-
584-
avg_spans = heatmap_sums / heatmap_counts
585-
indices = np.indices((num_x_wins, num_y_wins))
586-
x_coords = indices[0] * win_x_size
587-
y_coords = indices[1] * win_y_size
578+
x_start = max(0, x_starts[u] - 1)
579+
x_end = max(0, x_ends[u] - 1)
580+
y_bin = max(0, y_starts[u] - 1)
581+
heatmap_counts[x_start : x_end + 1, y_bin] += 1
582+
583+
x_coords = np.repeat(x_bins[:-1], num_y_bins)
584+
y_coords = np.tile(y_bins[:-1], num_x_bins)
588585

589586
df = pd.DataFrame(
590587
{
591-
"genomic_position": x_coords.flatten(),
588+
"position": x_coords.flatten(),
592589
"time": y_coords.flatten(),
593-
"average_ancestor_span": avg_spans.flatten(),
590+
"overlapping_node_count": heatmap_counts.flatten(),
594591
}
595592
)
596593
return df.astype(
597594
{
598-
"genomic_position": "int",
595+
"position": "int",
599596
"time": "int",
600-
"average_ancestor_span": "float64",
597+
"overlapping_node_count": "int",
601598
}
602599
)

pages/nodes.py

+30-8
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,38 @@ def page(tsm):
5757
)
5858

5959
plot_options = pn.Column(
60-
pn.pane.Markdown("# Plot Options"),
6160
log_y_checkbox,
6261
)
6362

64-
anc_span_data = tsm.compute_ancestor_spans_heatmap_data()
65-
heatmap = hv.HeatMap(anc_span_data).opts(
66-
width=config.PLOT_WIDTH,
67-
height=config.PLOT_HEIGHT,
68-
tools=["hover"],
69-
colorbar=True,
63+
def make_heatmap(num_x_bins, num_y_bins):
64+
anc_span_data = tsm.compute_ancestor_spans_heatmap_data(num_x_bins, num_y_bins)
65+
heatmap = hv.HeatMap(anc_span_data).opts(
66+
width=config.PLOT_WIDTH,
67+
height=config.PLOT_HEIGHT,
68+
tools=["hover"],
69+
colorbar=True,
70+
)
71+
return heatmap
72+
73+
max_x_bins = int(np.sqrt(df_nodes.child_right.max()))
74+
x_bin_slider = pn.widgets.IntSlider(
75+
name="genome bins",
76+
value=min(50, int((max_x_bins - 1) / 2)),
77+
start=1,
78+
end=max_x_bins,
79+
)
80+
max_y_bins = int(np.sqrt(df_nodes.time.max()))
81+
y_bin_slider = pn.widgets.IntSlider(
82+
name="time bins", value=min(50, int(max_y_bins / 2)), start=1, end=max_y_bins
7083
)
84+
hm_options = pn.Column(x_bin_slider, y_bin_slider)
7185

72-
return pn.Column(main, hist_panel, heatmap, plot_options)
86+
hm_panel = pn.bind(
87+
make_heatmap,
88+
num_x_bins=x_bin_slider,
89+
num_y_bins=y_bin_slider,
90+
)
91+
92+
return pn.Column(
93+
main, pn.Column(hist_panel, plot_options), pn.Column(hm_panel, hm_options)
94+
)

0 commit comments

Comments
 (0)