navis-org / pymaid

Python library to interface with CATMAID servers. Fully interoperable with navis.
https://pymaid.readthedocs.io/en/latest/
GNU General Public License v3.0
24 stars 11 forks source link

Plotting multi-group neurons with distinct Colors for Axons, Dendrites, and Soma #240

Open KeJiiii opened 1 year ago

KeJiiii commented 1 year ago

Hi,

I have a question about visualizing neuron substructures and region volumes with distinct colors in a 3D view. I have two groups of neurons, and each group is labeled for soma, axon, and dendrites in SWC files. I would like to assign six different colors to represent these components for each group. Furthermore, I want to visualize them in 3D along with the region volumes. Are there function for this purpose?

Thank you in advance!

KeJiiii commented 1 year ago

Now, I have accomplished this by adding a column in neuron.nodes that contains 6 labels and the same property in volume, which can be recognized by color_by. However, the colors cannot be manually defined,they can only be defined through a palette.

ne = navis.read_swc(...)
re = navis.read_mesh(...)
for i in range(len(ne)):   # To add 'AD' column to a single neuron.

    ne[i].nodes.loc[(ne[i].nodes['label'] == 1)&("STR_warp" in ne.name[i]), 'AD'] = 1
    ne[i].nodes.loc[(ne[i].nodes['label'] == 2)&("STR_warp" in ne.name[i]), 'AD'] = 2
    ne[i].nodes.loc[(ne[i].nodes['label'] == 3)&("STR_warp" in ne.name[i]), 'AD'] = 3
    ne[i].nodes.loc[(ne[i].nodes['label'] == 1)&("IN_warp" in ne.name[i]), 'AD'] = 4
    ne[i].nodes.loc[(ne[i].nodes['label'] == 2)&("IN_warp" in ne.name[i]), 'AD'] = 5
    ne[i].nodes.loc[(ne[i].nodes['label'] == 3)&("IN_warp" in ne.name[i]), 'AD'] = 6

re.AD=([7] * 290624)  # vertices
fig=navis.plot3d([ne,re], backend='k3d',color_by="AD",palette="tab20")  
schlegelp commented 1 year ago

Hi.

You should be able to pass a dictionary as palette to set colors for specific values. For that to work your label column must be categorical instead of numerical though:

# Convert label column to strings (interpreted as categorical)
for n in ne:
   n.nodes['AD'] = n.nodes.AD.astype(str)

# Define palette (note you can also use (r, g, b) instead of "red", "blue", etc.)
palette = {"1": "red", "2": "blue", "3": "green", "4": "purple", "5": "magenta", "6": "white"}

# Plot
fig = navis.plot3d([ne, re], backend='k3d', color_by="AD", palette=palette)