-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Spatial data plot visualization requirements #913
Comments
Potentially 3-4 panel plot
|
Opened branch "feature-spatial-visualization" to address this |
First pass at a 4-panel plot using a selection of genes. This was made in a Jupyter notebook, hence the dark theming. I used a combination of scanpy and matplotlib to make this. Note I removed the colorbar from the stacked violin plot because the scanpy people removed the colorbar with their own horizontal "legend" object, and I could not create a vertical colorbar using their StackedViolin figure object. |
Notebook found at 809996e |
@hertzron wanted to see a full-tissue version of the plots, so here is one. I also added Atoh1 to this and the previous plot for funsies. With more cells to evaluate, the low-expression (dark) green is harder to see with the dark background |
Version where we use the default "white" background but make the UMAP black (according the Mike Hoa's suggestion). Also good matplotlib practice for me. #4th iteration
plt.style.use('default')
# Split into 2 top/bottom subfigures. Top side will be spatial and umap plots, and bottom side will be "stacked violin" plot
fig = plt.figure(figsize=(30, 12))
subfigs = fig.subfigures(2,1)
#subfigs[0].subplots_adjust(hspace=0.5)
ax0 = subfigs[0].subplots(2, num_genes+2)
ax_col = 0
for gene in marker_genes:
sc.pl.spatial(vis_adata, img_key="hires", color=gene, size=1, library_id="D1_hires_image", ax=ax0[0][ax_col], color_map="YlGn_r", show=False)
sc.pl.umap(vis_adata, color=gene, ax=ax0[1][ax_col], color_map="YlGn_r", na_color="gray", show=False)
# remove umap title (using title=None doesn't work)
ax0[1][ax_col].set_title("")
ax0[1][ax_col].set_facecolor("#000000")
ax_col +=1
# clusters
sc.pl.spatial(vis_adata, img_key="hires", color="spatial_clusters", size=1, library_id="D1_hires_image", legend_loc=None, ax=ax0[0][ax_col], show=False)
sc.pl.umap(vis_adata, color="spatial_clusters", ax=ax0[1][ax_col], show=False)
# remove umap title (using title=None doesn't work)
ax0[1][ax_col].set_title("")
ax0[1][ax_col].set_facecolor("black")
ax_col +=1
# blank image
sc.pl.spatial(vis_adata, img_key="hires", color=None, size=1, library_id="D1_hires_image", ax=ax0[0][ax_col], show=False)
# remove axes for ax0[ax_row][1]
ax0[1][ax_col].axis("off")
# Stacked Violin plot
ax1 = subfigs[1].subplots(nrows=1, ncols=1)
dotplot_fig = sc.pl.dotplot(vis_adata, marker_genes, title="Marker gene expression per cluster", groupby="spatial_clusters", ax=ax1, swap_axes=True, cmap="YlGn_r", show=False, return_fig=True)
dotplot_fig.make_figure()
dotplot_axes = dotplot_fig.fig.get_axes()
# For some reason, deleting all axes and remaking the figure makes it without the spacer above the plot (which was in ax[2] I think)
for ax in dotplot_axes:
dotplot_fig.fig.delaxes(ax)
dotplot_fig.make_figure()
#dotplot_fig.get_axes()["mainplot_ax"].patch.set_facecolor("white") |
Minor adjustment between this plot and the last.
|
At a recent gEAR planning meeting there were some suggestions for a slimmed down viewer. This would be separate from a curator and would be an extension of the current gene expression view functionality but just for spatial data
|
Matplotlib also does support event handling and the last example shows how to click a point to generate a new plot, which I guess we would specify to be in the "zoom" figure. Look into the ResizeEvent It might also be worth exploring the WebAgg backend, which on |
Holoviews is cool but you cannot import a Matplotlib figure into the tool. You have to use Holoviews itself with a Matplotlib backend to render a figure. Since we use scanpy to create the spatial plot, this is not ideal. There are ways to convert the image data into numpy and try to render the spatial multi-panel plot without scanpy, but I deem that too complicated for the moment. Next thing up to try is Panel (https://panel.holoviz.org/) which supports embedding Matplotlib within a panel. Almost like making a dashboard. |
Also going to investigate mpld3 (https://github.com/mpld3/mpld3) which seems pretty well maintained, has a decent amount of stars, and seems exactly the tool for the job EDIT: Tested this, and after 10 minutes the tool is still trying to convert my 3 panel figure into a d3 object. I believe the issue is trying to convert the image itself. However it does have the ability to create custom plugins. One of the tutorials (https://nbviewer.org/github/mpld3/mpld3/blob/master/notebooks/custom_plugins.ipynb) showcases how to make custom plugins, and their example injects text of Hello World into the plot, so this gives me hope that I could plot without the images and then inject the image as a background. However zooming in on the Hello World plot does not zoom in the text, so maybe this isn't the way to go. I do believe there is some merit to using this for normal tSNE/UMAP plots though as there is the possibility of creating hoverable tooltips and zooming. EDIT 2: From the FAQ for this tool.
|
Panel seems nice. You could create a Pane with a Matplotlib spec and add some component/widget controls. It could serve our needs. However, Panel needs a server to run.... it won't run on the same Flask. Moreover since Panel has Flask under the hood (I think), we would have to set it as a different port. I think the general flow would be:
One way we could try to avoid balancing different port numbers is just to run the Panel server as a Cloud Run Function in a serverless capacity. Though we'd still have to provide a way to run it locally as well. Example of flask embedding is in this command https://discourse.holoviz.org/t/panel-regression-embedding-panel-in-gunicorn-flask/1724/6 |
November 22, 2024 standupShowed Panel-based viewer to Ronna and co. Feedback was well-received. She envisioned a situation where you can take unannotated clusters (like the single-cell workbench), and when you select a region to zoom in or select a specific cluster, it will recluster within that region. I did note the scope of the panel currently was for the gene expression viewer, but we can make it work for other tools too. Other things:
|
This is a list in flux
The text was updated successfully, but these errors were encountered: