diff --git a/exercises/navis/navis_exercise_2.ipynb b/exercises/navis/navis_exercise_2.ipynb index 5ed58dd..b3e6b5e 100644 --- a/exercises/navis/navis_exercise_2.ipynb +++ b/exercises/navis/navis_exercise_2.ipynb @@ -598,8 +598,8 @@ "outputs": [], "source": [ "# NAVis pre-computes two kinds of segments:\n", - "print('Linear segmnents that maximmize segment lengths:', len(n.segments))\n", - "print('Linear segmnents between branch/leaf nodes:', len(n.small_segments))\n", + "print(\"Linear segmnents that maximmize segment lengths:\", len(n.segments))\n", + "print(\"Linear segmnents between branch/leaf nodes:\", len(n.small_segments))\n", "\n", "# For the tortuosity we need to use the latter!\n", "\n", @@ -628,9 +628,7 @@ "node_locs = dict(zip(n.nodes.node_id, n.nodes[[\"x\", \"y\", \"z\"]].values))\n", "dist_eucl = []\n", "for seg in n.small_segments:\n", - " dist_eucl.append(\n", - " np.linalg.norm(node_locs[seg[0]] - node_locs[seg[-1]])\n", - " )\n", + " dist_eucl.append(np.linalg.norm(node_locs[seg[0]] - node_locs[seg[-1]]))\n", "dist_eucl = np.array(dist_eucl)\n", "\n", "# Inspect the results\n", @@ -676,7 +674,7 @@ "dist_geo = []\n", "for seg in n.small_segments:\n", " dist_geo.append(\n", - " nx.shortest_path_length(n.graph, source=seg[0], target=seg[-1], weight='weight')\n", + " nx.shortest_path_length(n.graph, source=seg[0], target=seg[-1], weight=\"weight\")\n", " )\n", "dist_geo = np.array(dist_geo)\n", "dist_geo[:10]" @@ -791,7 +789,7 @@ "from scipy.cluster.hierarchy import linkage, cut_tree\n", "\n", "# Drop neurons that don't have a t-type assigned\n", - "nl_w_ttype = nl[nl.t_type != 'nan']\n", + "nl_w_ttype = nl[nl.t_type != \"nan\"]\n", "\n", "# First we will drop neurons that have not t-type assigned\n", "ivscc_w_ttype = ivscc[nl_w_ttype.id]\n", @@ -801,13 +799,17 @@ "ivscc_filled = ivscc_w_ttype.fillna(0)\n", "\n", "# Normalize the data to be between 0 and 1\n", - "ivscc_scaled = (ivscc_filled + ivscc_filled.min()) / (ivscc_filled.max() - ivscc_filled.min())\n", + "ivscc_scaled = (ivscc_filled - ivscc_filled.min(axis=1).values.reshape(-1, 1)) / (\n", + " ivscc_filled.max(axis=1) - ivscc_filled.min(axis=1)\n", + ").values.reshape(-1, 1)\n", + "\n", + "ivscc_scaled.fillna(0, inplace=True)\n", "\n", "# Calculate the Euclidean distance\n", "dist = pdist(ivscc_scaled.T)\n", "\n", "# Perform hierarchical clustering\n", - "Z = linkage(dist, method='ward')\n", + "Z = linkage(dist, method=\"ward\")\n", "\n", "# Cut the tree to get the clusters\n", "labels = cut_tree(Z, n_clusters=40).flatten()\n", @@ -815,9 +817,9 @@ "# Combine cluster labels and t-types into a dataframe\n", "clusters = pd.DataFrame()\n", "\n", - "clusters['id'] = nl_w_ttype.id\n", - "clusters['t_type'] = nl_w_ttype.t_type\n", - "clusters['cluster'] = labels\n", + "clusters[\"id\"] = nl_w_ttype.id\n", + "clusters[\"t_type\"] = nl_w_ttype.t_type\n", + "clusters[\"cluster\"] = labels\n", "clusters.head()" ] }, @@ -834,9 +836,9 @@ "confusion = pd.crosstab(clusters.t_type, clusters.cluster)\n", "\n", "# Sort rows and columns by hierarchical clustering\n", - "row_linkage = linkage(pdist(confusion), method='ward')\n", + "row_linkage = linkage(pdist(confusion), method=\"ward\")\n", "row_order = leaves_list(row_linkage)\n", - "col_linkage = linkage(pdist(confusion.T), method='ward')\n", + "col_linkage = linkage(pdist(confusion.T), method=\"ward\")\n", "col_order = leaves_list(col_linkage)\n", "\n", "# Apply the sorting\n", @@ -853,13 +855,20 @@ "outputs": [], "source": [ "# For each t-type, generate a color based on how the first label\n", - "first_labels = np.unique(confusion.index.map(lambda x: x.split(' ')[0]))\n", + "first_labels = np.unique(confusion.index.map(lambda x: x.split(\" \")[0]))\n", "\n", "cmap = {}\n", "for t, base_color in zip(first_labels, sns.color_palette(\"tab10\", len(first_labels))):\n", " # All labels starting with `t`\n", " t_labels = [ix for ix in confusion.index if ix.startswith(t)]\n", - " cmap.update(dict(zip(t_labels,sns.light_palette(base_color, n_colors=len(t_labels) * 2)[::-1])))" + " cmap.update(\n", + " dict(\n", + " zip(\n", + " t_labels,\n", + " sns.light_palette(base_color, n_colors=len(t_labels) * 2)[::-1],\n", + " )\n", + " )\n", + " )" ] }, { @@ -870,26 +879,31 @@ "outputs": [], "source": [ "# Plot the confusion matrix as scatter heatmap\n", - "confusion_pivot = confusion.unstack().reset_index().rename(columns={0: 'count'})\n", + "confusion_pivot = confusion.unstack().reset_index().rename(columns={0: \"count\"})\n", "\n", "\n", "# Turn the cluster into a string - otherwise seaborn will re-order it\n", - "confusion_pivot = confusion_pivot.astype({'cluster': \"string\", 't_type': \"string\"})\n", + "confusion_pivot = confusion_pivot.astype({\"cluster\": \"string\", \"t_type\": \"string\"})\n", "\n", "g = sns.relplot(\n", " data=confusion_pivot,\n", - " y=\"t_type\", x=\"cluster\", size=\"count\",\n", - " palette=cmap, hue=\"t_type\",\n", + " y=\"t_type\",\n", + " x=\"cluster\",\n", + " size=\"count\",\n", + " palette=cmap,\n", + " hue=\"t_type\",\n", " edgecolor=\".7\",\n", - " col_order=confusion.index.values, row_order=confusion.columns.values,\n", - " height=10, sizes=(0, 400),\n", - " legend=False\n", + " col_order=confusion.index.values,\n", + " row_order=confusion.columns.values,\n", + " height=10,\n", + " sizes=(0, 400),\n", + " legend=False,\n", ")\n", "\n", "ax = g.axes[0, 0]\n", "\n", - "ax.set_ylabel('Transcriptomic type')\n", - "ax.set_xlabel('Morphological cluster')" + "ax.set_ylabel(\"Transcriptomic type\")\n", + "ax.set_xlabel(\"Morphological cluster\")" ] }, {