Skip to content
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

color legend for categorical annoation in table #242

Closed
ynanli opened this issue May 17, 2024 · 8 comments · Fixed by #320
Closed

color legend for categorical annoation in table #242

ynanli opened this issue May 17, 2024 · 8 comments · Fixed by #320
Assignees
Labels
enhancement New feature or request

Comments

@ynanli
Copy link

ynanli commented May 17, 2024

Hi,
I am using the viewer to visualize the categorical labels in the table (e.g., cell types) from steinbock-generated data. The viewer plots perfectly, even with a subsetted table. However, it is hard to figure out which labels they are on the image as they are color-coded without a legend.
I tried to look at the values shown in the viewer but without success. The indices of the table and label image start differently (0 for image, 1 for table), and it becomes even worse with the subsetted table.

I included a snapshot of the viewer with a subsetted table. My cursor was on one of the orange cells. Is there a way to figure out what these colors mean? Many thanks!

grafik

@melonora
Copy link
Collaborator

So regarding the different indices, this is because 0 is usually seen as background. As for which categories are there, I have thought of this before and I think providing hover tooltip functionality based on which column the user is coloring would benefit here. I just didn't have time yet with the recent annotation_widget work:)

So TLDR no not yet, but it is in our radar.

@LucaMarconato
Copy link
Member

LucaMarconato commented Jun 10, 2024

The indices mismatch bug has also been reported by @fjorka via Zulip. We have a strategy to fix this, discussed in the linked issue #248.

@LucaMarconato
Copy link
Member

Another user (@gboscagli) reported this issue so I looked better into this.

I used this code:

##
from spatialdata.datasets import blobs_annotating_element
from napari_spatialdata import Interactive
import spatialdata as sd

sdata = blobs_annotating_element('blobs_labels')

##
labels = sdata['blobs_labels']

print(sd.get_element_instances(labels))
sdata['table'].obs.index = list(map(str, [100, 101, 102, 103, 104]))
print(sdata['table'].obs)
print(labels.data.compute().tolist())

Interactive(sdata)

These are the outputs of the first 2 prints.

Index([2, 3, 4, 5, 6], dtype='int16')

           region  instance_id
100  blobs_labels            2
101  blobs_labels            3
102  blobs_labels            4
103  blobs_labels            5
104  blobs_labels            6

And in the screenshot you can see the output of the third print and the napari plot.
Screenshot 2024-08-27 at 16 58 08

What I see from napari is correct:

  • the color of the cells is correct
  • the value appearing in the bottom status bar is correct (it corresponds to the instance_id)
  • in particular, the blobs have the background and skip the 1 value, so everything seems to be correct also when some gaps are present in the indices.

Therefore my conclusions are:

  1. Either I failed to reproduce the bug, in such case please @gboscagli @fjorka @ynanli a short code I could run would help.
  2. Either (I bet on this) the problem is a misunderstanding between the instance_id values and the indices of obs. If this is the case we should clarify in the docs and tutorials that we never use the obs.index values but the instance_id instead. The reasons are:
    1. that a single AnnData object can be associated to multiple elements, so the pair of columns region_key + instance_key is needed (and AnnData does not support pandas multiindices.
    2. the index of the table can changes often after operations are performed on the table (like a reindexing). This could potentially make it easy for the user to lose the link between the table and the shapes. We wanted something more persistent such as a separate column.

@ynanli
Copy link
Author

ynanli commented Aug 27, 2024

Hi @LucaMarconato,
Thanks for following up. I think our issue was rather came with the 'subsetted' table.

I also tried with the blobs data with the following code:

##
from spatialdata.datasets import blobs_annotating_element
from napari_spatialdata import Interactive
import spatialdata as sd

sdata = blobs_annotating_element('blobs_labels')

##
labels = sdata['blobs_labels']
print(sdata['table'].obs)
sdata['table'] = sdata['table'][["0", "2", "4"],]
print(sdata['table'].obs)

Interactive(sdata)

These are the outputs of the prints:

         region  instance_id
0  blobs_labels            0
1  blobs_labels            2
2  blobs_labels            3
3  blobs_labels            4
4  blobs_labels            5
5  blobs_labels            6

         region  instance_id
0  blobs_labels            0
2  blobs_labels            3
4  blobs_labels            5

And a screenshot of napari plot, where my cursor is pointing at the greenish label#3:
grafik

It reads the label value correctly and the color is correct. But the values from the table cannot be read, as shown [No Properties] in the status bar.

The status bar becomes this when i move the cursor to the background where instance_id = 0:
grafik

Of a side note, we put the ObjectNumber as the instance key, which is the cell_id from the steinbock pipeline. I hope that is correct.

table = TableModel.parse(adata_subset, region=adata_subset.obs.region.unique().tolist(), region_key="region", instance_key="ObjectNumber")

@gboscagli
Copy link

@LucaMarconato @melonora
I reproduced the shift bug using blobs dataset. Here is the code:

from spatialdata.datasets import blobs_annotating_element
from napari_spatialdata import Interactive
import spatialdata as sd

sdata = blobs_annotating_element('blobs_labels')

##
labels = sdata['blobs_labels']

print(sd.get_element_instances(labels))
obs = sdata['table'].obs
obs['strings'] = ['A', 'A', 'B', 'B', 'C', 'C']

##
sdata["table"].uns["strings_colors"] = {"A": "#FF5733", #red
                                        "B": "#3498DB", #blue
                                        "C": "#2ECC71" #green
                                        }

Interactive(sdata)

As a reference, I leave here the print of the obs df:

         region  instance_id strings
0  blobs_labels            0       A
1  blobs_labels            2       A
2  blobs_labels            3       B
3  blobs_labels            4       B
4  blobs_labels            5       C
5  blobs_labels            6       C

As you can see from the image, I have the pointer over the blob 4, as per the instance_id. Also, blob 4 is colored in blue as the manual colormap in uns suggests. However, the associated value is "C", that would be correct if we considered the index, not the instance_id.
image

Moreover, if I place myself over the blob 6, the value is "No Properties" because index 6 doesn't exist.

image

I would stress on the fact that colors are actually correct, so no problem for an overall visualization. However, to visualize the relative annotation, Napari seems to refer to the index of obs and it's kinda misleading: this problem is consistent with what @ynanli found out, but i think it's not dependent on the subsetting since I didn't perform any.

@LucaMarconato LucaMarconato self-assigned this Sep 15, 2024
@LucaMarconato LucaMarconato added the enhancement New feature or request label Sep 15, 2024
@LucaMarconato
Copy link
Member

Thanks for the example, I just tried reproducing but as you can see from my initial screenshot, I don't see the last part in the status bar e.g. "; [No Properties].

@ynanli @gboscagli which versions of napari and napari-spatialdata are you using?

I am using napari==0.5.3.dev30+g3b5b3a98 and the latest main of napari-spatialdata.

@LucaMarconato
Copy link
Member

LucaMarconato commented Sep 30, 2024

Hi, no need to send the versions. I made a fix in this PR: #320

Two comments:

@LucaMarconato
Copy link
Member

CC @berombau (tagging you since you mentioned this issue once): I am merging a fix now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants