flatironinstitute / CaImAn

Computational toolbox for large scale Calcium Imaging Analysis, including movie handling, motion correction, source extraction, spike deconvolution and result visualization.
https://caiman.readthedocs.io
GNU General Public License v2.0
641 stars 370 forks source link

Download high resolution analysis figure #1105

Closed zhouyi0812 closed 1 year ago

zhouyi0812 commented 1 year ago

Hello!!

After I run the algorithm and get the individual cell with a time series graph. I wonder if there is a way to down load the individual cell graph in high resolution.

Thank you!!

EricThomson commented 1 year ago

The spatial footprints are in estimates.A, the time series are in different parts of estimates, so it depends if you want time series or not, and if so which ones. But you can plot these things using matplotlib and then save them as png with dpi as a parameter. For lines you can save as vectorized images.

zhouyi0812 commented 1 year ago

I tried this code, but the image I saved is blank.

cnm.estimates.plot_contours_nb(img=cn_filter, idx=cnm.estimates.idx_components) plt.savefig('contour.png', dpi=600) the outcome is <Figure size 640x480 with 0 Axes>

And then I adjust to this and successfully saved an image without any components. cnm.estimates.plot_contours_nb(img=cn_filter) plt.savefig('contour.png', dpi=600)

For spatial footprints, I only want to save an example of how the cell look like in the whole graph, but I am not sure how to do that.

Thank you!

kushalkolar commented 1 year ago

I'm pretty sure that plot_contours_nb creates a bokeh plot, whereas plt.savefig is from matplotlib, you can't use matplotlib to save a bokeh plot.

I think the bokeh toolbar has a save button if that's all you want?

zhouyi0812 commented 1 year ago

I saw the button on the left of the graph, but the resolution is quite low and I want a high resolution one.

kushalkolar commented 1 year ago

To create high resolution publication quality figures, the best option is really matplotlib. The various attributes of the estimates object are numpy arrays and you can plot them with matplotlib. Jake Vanderplas has a great matplotlib tutorial, I think he has a youtube tutorial as well: https://jakevdp.github.io/PythonDataScienceHandbook/04.00-introduction-to-matplotlib.html

zhouyi0812 commented 1 year ago

Thank you for your guidance, I will figure out the matplotlib myself. I just want to double check, the parameter I should play with that represents the accepted and rejected components are:

cnm.estimates.C and cnm.estimates.idx_components

But I just a bit confused, how is individual cell can be separate from: cnm.estimates. hv_view_components(img=cn_filter, idx=cnm.estimates.idx_components, denoised_color='red', cmap='gray')

Thank you very much!!!

kushalkolar commented 1 year ago

estimates.C is of shape [n_components, n_frames], you can slice along the first dimension n_components using estimates.idx_components, i.e. estimates.C[estimates.idx_components]

For more info: https://caiman.readthedocs.io/en/master/Getting_Started.html#result-variables-for-2p-batch-analysis

if you want mor complex plots like heatmaps use seaborn which builds upon matplotlib: https://seaborn.pydata.org/generated/seaborn.heatmap.html

zhouyi0812 commented 1 year ago

Hello!

Thank you! I have successfully sliced individual cell by applied the code you provided with adding cnm. in front of the estimates.C

But I am still stuck in how to get the 'cnm.estimates.plot_contours_nb(img=cn_filter, idx=cnm.estimates.idx_components)' out of the code with matplotlib.

I want a graph of the high resolution of cell segmentation (contour plot)

I have tried and deleted plot_contour, but just didn't figure out: plt.figure(); plt.imshow(cnm.estimates.plot_contours_nb(img=cn_filter, idx=cnm.estimates.idx_components), dims, order='F')

Thank you very much!!!

EricThomson commented 1 year ago

Based on Gitter it seems you got this working. It would be helpful if you put a code snippet to show what you did, so others that find this can see what to do.

zhouyi0812 commented 1 year ago

Sure! Here is my code based on the demo CNMF-E

  1. Working code for visualizing individual cell

plt.figure(); plt.imshow(np.reshape(cnm.estimates.A[:,cnm.estimates.idx_components[0]].toarray(), dims, order='F')) plt.savefig('cell.png',dpi=700) plt.figure(); plt.plot(cnm.estimates.C[cnm.estimates.idx_components[0]]) cnm.estimates.view_components()

  1. The separate two graphs: all cells (FOV) and contour

import matplotlib.pyplot as plt

Assuming P is the existing graph

Assuming cnm.estimates.coordinates is the list of contours

Create a new figure with subplots

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))

Plot the graph p (all cells) in the first subplot

ax1.imshow(cn_filter) ax1.set_xlabel('X') ax1.set_ylabel('Y') ax1.set_title('Graph p')

Plot the contours in the second subplot

for contour_dict in cnm.estimates.coordinates: contour_coords = contour_dict['coordinates'] ax2.plot(contour_coords[:, 0], contour_coords[:, 1], color='pink', linewidth=1) ax2.set_xlabel('X') ax2.set_ylabel('Y') ax2.set_title('Contours of Cells')

Adjust spacing between subplots

plt.tight_layout()

Display the combined figure

plt.show()

  1. Plot contour upon the the FOV

import matplotlib.pyplot as plt

Assuming P is the existing graph

Assuming cnm.estimates.coordinates is the list of contours

Plot the cells on the existing graph

plt.figure(p.number) # Set the current figure to the existing graph plt.imshow(cn_filter) plt.xlabel('X') plt.ylabel('Y') plt.title('Graph P')

Plot the contours on top of the cells

for contour_dict in cnm.estimates.coordinates: contour_coords = contour_dict['coordinates'] plt.plot(contour_coords[:, 0], contour_coords[:, 1], color='black', linewidth=1)

Display the combined graph

plt.show()

EricThomson commented 1 year ago

Great thanks! Closing the issue as it seems resolved (incidentally, when you feel an issue is resolved you can click Close issue at the bottom of the issue page).