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

Add histogram #49

Open
tlambert03 opened this issue Oct 10, 2024 · 7 comments
Open

Add histogram #49

tlambert03 opened this issue Oct 10, 2024 · 7 comments
Assignees

Comments

@tlambert03
Copy link
Member

opening an issue to discuss adding a histogram (which everyone agrees is a must-have feature)

@gselzer has done a lot of work here, currently in https://github.com/gselzer/ndv/tree/interactive-clims

I had a similar vispy-backed histogram that controlled the napari LUTs back in napari/napari#675 ... at one point, I had put a lot of work/consideration into it, and that branch is still at https://github.com/tlambert03/napari/tree/histogram

backend considerations

we have a few options for tools we could use to create the actual histogram graph

  • Qt's Graphics View. This is what's used, for example, in pyqtgraph's histogram. The benefit here is that it would work regardless of what canvas backend we use for the image itself (e.g. vispy or pygfx). The downside is that it won't translate easily to a future jupyter widget.
  • Directly create them in backends like vispy (as @gselzer did in his branch and I did in [WIP] Histogram with 2-way LUT control napari/napari#675). This has the advantage of being easily portable to jupyter (see Feature: make useable with Jupyter #48), but the disadvantage of needing to be implemented in each backend. (which again, can re-raise the discussion of whether we want to keep supporting multiple canvas backends)

wants

here's a partial list of things that one might want in a histogram. not all of these are mandatory for an initial implementation.

  • axes with ticks & numbers that pan/zoom with the histogram itself
  • full styling API: colors for face, background, text, ticks etc... font sizes, line widths
  • ability to turn off stylings for a bare minimal histogram (e.g. that could be put on a slider as in @gselzer's demo)
  • separation of histogram calculation logic from display logic
  • min/max/gamma controls for connection with a LUT model
  • some consideration for how we will display multiple channels (in fluorescence) or overlaid RGB
@gselzer
Copy link
Collaborator

gselzer commented Oct 11, 2024

If you want to assign this to me @tlambert03 I'm happy to keep hacking along 😄

I had some further discussions with @marktsuchida and @nicost yesterday, which I'll summarize below:

Additional Wants:

  • Toggle-able logarithmic y-axis to view distribution tails
  • Enable removal of a variable percentage of outliers in autoscale (ignore percentage in mmstudio)
  • Display of additional statistics (mmstudio has average, standard deviation)
  • Restrict calculation within ROIs
  • Variable bin counts - @marktsuchida brought up the point that mmstudio has one bin per unique value in the data, while the prototype is fixed 256 bins. There are certainly speed/precision tradeoffs and we could enable different bin counts in different locations (see plan below)

Backend Considerations:

  • Naively, I would think that showing a viewer in Jupyter is important, so I would hesitate to implement these histograms in Qt. But I don't have the experience to feel strongly that way.
  • I am expecting that once we get things looking nice in vispy, pygfx won't be too tricky to knock out. 🤜 🪵

my current plans (up for debate/revision):

  • Stick with the current prototype (screenshot below) for initial visualization - I'd argue it gives you a nice overview with a small footprint. We can clean it up visually as needed, but I don't think we should add much more on top of what currently exists.
  • Experiment with fast-histogram, which should hopefully be enough for our needs. If we need better histograms, it would be great to plug in a better solution, but it might be nice to wait until that's needed.
  • Enable a double-click on any channel histogram to pop up a dedicated widget for that channel only, providing some/all of the wants that we've listed above.

image

@tlambert03
Copy link
Member Author

thanks @gselzer! I do want you to keep hacking along, but I do really want to organize my work in https://github.com/tlambert03/napari/tree/histogram for you to have a look at as well. As mentioned, this is something that I spent a good month on at one point and so I'd like to make sure that all the stuff learned back then is accounted for here as well. I started to do this in https://github.com/tlambert03/ndv/tree/histogram (see the x.py example), and will clean it up soon.

@tlambert03
Copy link
Member Author

Toggle-able logarithmic y-axis to view distribution tails

I had this working in napari/napari#675 (comment)

Enable removal of a variable percentage of outliers in autoscale (ignore percentage in mmstudio)
Display of additional statistics (mmstudio has average, standard deviation)
Restrict calculation within ROIs
Variable bin counts

these are all great, but should live in the statistics calculating thing (not the histogram PR). Let's just make a histogram component, and then think about how it lives within a more complex composite statistics display. The histogram widget basically just needs to take bins and show them.

So, if you want to open an independent PR to discuss a (non-GUI) stats engine, that would be great too. Basically, the GUI object should be disconnected from the calculation object.

@tlambert03
Copy link
Member Author

another thing that that previous PR had was a shared mechanism for line scans: napari/napari#675 (comment)

so, it should be possible to share a lot of logic between a plot widget and a histogram widget (namely, keeping axes aligned with data and pan-zoom stuff)

@gselzer
Copy link
Collaborator

gselzer commented Oct 11, 2024

thanks @gselzer! I do want you to keep hacking along, but I do really want to organize my work in https://github.com/tlambert03/napari/tree/histogram for you to have a look at as well.

Yes, definitely important, let me know when you feel like things are in a good spot for review and I'll be happy to read over things.

So, if you want to open an independent PR to discuss a (non-GUI) stats engine, that would be great too. Basically, the GUI object should be disconnected from the calculation object.

I agree on multiple PRs, I was partially using this comment as a way to pin down all of my thoughts in the open before the action items slipped from my memory 😅

@gselzer
Copy link
Collaborator

gselzer commented Oct 11, 2024

another thing that that previous PR had was a shared mechanism for line scans: napari/napari#675 (comment)

so, it should be possible to share a lot of logic between a plot widget and a histogram widget (namely, keeping axes aligned with data and pan-zoom stuff)

Also worth noting these operations are rather interconnected with the existing ROI interoperability. We may want to track a separate issue for expanding ROI capabilities (adding additional ROIs like lines, ellipses, polygons, etc., as well as signals to keep track of their changes that the statistics engine could listen for).

@tlambert03
Copy link
Member Author

ok @gselzer, have a look at https://github.com/tlambert03/ndv/tree/histogram

it's the bones of "plot" widget, where self._view is a viewbox ready for a histogram, line plot, etc... Still needs conveniences to hide/show the various axes, and we might consider a cross-platform API for accessing/styling/hiding/showing various components. Something like a "WidgetHandle" or a LabelHandle... I don't know, maybe that's overkill. Anyway, let me know if we've basically done the same thing so far :)

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

No branches or pull requests

2 participants