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

Configurable choices of stretches and colormaps? #10

Open
robintw opened this issue May 20, 2016 · 9 comments
Open

Configurable choices of stretches and colormaps? #10

robintw opened this issue May 20, 2016 · 9 comments

Comments

@robintw
Copy link
Collaborator

robintw commented May 20, 2016

I really love the dropdown lists for stretches and colormaps on the toolbar at the top of the image viewer windows. However, they don't seem to have quite the values I want in them!

Specifically, I'd like a stretch option of 98% and Green-Yellow-Red colormap (yes, I know, it's a bad colormap to use - but traditions die hard amongst colleagues). The default stretch option for satellite imagery is normally 98%...so it gets a lot of use in the field

However, I wonder if there is a better way to fix this - as all sorts of people will want custom settings for this. I've had a look at the code and can see where the stretch options are configured. I can also see that you have a settings class (and a simple settings editing GUI) where you can store configuration options.

What do you think about some extra settings that define the stretches to list in the dropdown (or maybe 'additional stretches' on top of the default ones?) - plus possibly even a setting for the default stretch to use in each new image viewer window?

(And then the same for the stretches, although that might be a bit more difficult depending how the icons for the dropdown are generated)

@astrofrog
Copy link
Member

For colormaps, we already have a way to register new colormaps:

http://glueviz.org/en/stable/customizing_guide/customization.html#custom-colormaps

and we could add a similar registry/decorator to add new scaling settings.

Note that this is not part of the settings, but settings is just used for simple options, while more complex extensions (data factories, colormaps, etc.) are done through separate registries. This is all done in glue/config.py.

@robintw
Copy link
Collaborator Author

robintw commented May 21, 2016

Ah perfect - I'll do a PR with a copy of that to do a similar registry for scaling settings.

I can't seem to find the right bit of the docs to find out exactly how plugins (like glue-geospatial) work, and exactly how they should be written/configured. Is it basically that anything that can be put in config.py can be put in a separate plugin?

@astrofrog
Copy link
Member

astrofrog commented May 21, 2016

@robintw - thanks!

For how plugins work - essentially yes, anything that can be put in a config.py file can also be put in a full package. Then the key bit of the package is this function:

https://github.com/glue-viz/glue-geospatial/blob/master/glue_geospatial/__init__.py#L1

which makes sure the relevant files get imported, or adds things to registries manually if needed. We then declare this as an entry point in the setup.py:

https://github.com/glue-viz/glue-geospatial/blob/master/setup.py#L9

When glue starts up, it looks at all the entry point functions and executes them all.

There are no docs to explain all this yet - if you fancy taking a stab at this, feel free to! (otherwise I can do it later this weekend or early next week).

@robintw
Copy link
Collaborator Author

robintw commented May 21, 2016

I've got a couple of questions on where exactly I should be modifying the list of stretches, when I implement a settings registry for stretches.

From looking at the code I can see two places that the stretches are defined - and in both places they are just hard-coded. One is in ContrastMode.menu_actions inside mouse_mode.py and one is inside AttributeLimitsHelper. I can't actually see anywhere that the latter class is used, and I see it has been added relatively recently - is this due to be integrated with some other stuff sometime? If so, should I leave well alone until that is done?

Once I've worked out where to put it, I think I should be able to deal with the settings registry for stretches fairly easily.

Interestingly, the ContrastMode class suggests that there is a mode you can enter where you can stretch the image by dragging the mouse...but I can't see this in any menu and can't really work out from the code how to enable it.

@astrofrog
Copy link
Member

@robintw - I added the attributes limit helper recently - it's part of the upcoming refactor for the viewers and is indeed not yet used.

I would recommend adding the new registry of stretches to the glue/config.py and then adapting both mouse_mode and AttributeLimitsHelper to then load the stretches from the stretch registry instead of hard-coding them. Does this make sense?

@astrofrog
Copy link
Member

Interestingly, the ContrastMode class suggests that there is a mode you can enter where you can stretch the image by dragging the mouse...but I can't see this in any menu and can't really work out from the code how to enable it.

When you click on the bias/contrast icon which gives the stretch options:

screen shot 2016-05-21 at 9 42 31 pm

Once that icon is clicked, you can control click and drag on the image to interactively change the contrast/bias. Can you get it to work?

@robintw
Copy link
Collaborator Author

robintw commented May 21, 2016

Ahhh! Yes, that works. I hadn't realised that the button was a 'toggle button' as well as a 'dropdown list button'.

Ideally it'd be great if that could be made more obvious, but I can't think of a way to do that...

@robintw
Copy link
Collaborator Author

robintw commented May 21, 2016

And yes, it makes sense to add the stretches registry and then use it in both places. I've just started implementing the code, and could do with some advice on a 'design decision'.

Each item in the registry will have two values: a label, and a 'stretch'. I'm trying to decide how to represent the stretch. I can see two options:

  1. The simplest would be just to store a single value (for the percentile), or two values (the low and the high, so that they can be non-symmetric) - something like ['98%', 2, 98]. However, this limits us to only configuring percentile stretches.
  2. The most flexible would be to store a function instead, which does whatever is needed for the stretch. Then, people could use this to implement percentile stretches, fixed absolute value stretches (eg. 0-255, 0-1, both of which are often used for satellite data), or crazy stretches implemented with a custom function (even including GUI dialogs)

I think number 2 is by far the best, but I'm not sure how best to go about implementing it. At the moment, the stretch dropdown options are linked to methods like ContrastMode.set_clip_percentile and ContrastMode.choose_vmin_vmax, and as those are methods of the ContrastMode instance they can't be referenced easily from the registry.

Is it worth refactoring all of the stretch functions out into a separate class? I can't quite think how best to do it, but there must be a sensible way to decouple them so that we can give the stretch registry a load of functions and then when an item is selected the function will be run on the correct viewer window.

Thoughts?

@astrofrog
Copy link
Member

astrofrog commented May 22, 2016

@robintw - great questions :)

I think it makes sense to store a function in the registry rather than just values (option 2). I can take a look to see how to recommend refactoring this in practice.

I think if we want to be the most general, we should actually have a separate registry for what I call 'interval' calculations and 'stretch' calculations. The first will return a lower and upper value, and the second will transform values in a 0-1 range to values in a 0-1 range through e.g. a non-linear mapping function. I implemented an API in Astropy to do this:

http://docs.astropy.org/en/stable/visualization/normalization.html

This is a generic non-astronomy-specific API, so I was thinking we could maybe use that API here to define some of the percentile intervals and existing functional stretches (since glue depends on astropy anyway - astropy has a lot of general scientific non-astro functionality). Note that the interval and stretch classes basically behave like functions, so this is consistent with what you are suggesting.

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