silx-kit / silx

silx toolkit
http://www.silx.org/doc/silx/latest/
MIT License
136 stars 74 forks source link

[plot] Display units in addition to the label of axes #2927

Open kif opened 4 years ago

kif commented 4 years ago

When the units are provided as attribute of an axis in a NXdata, I guess it would be quite easy to display them in addition to the label of the axis.

My use-case is quite simple: in SAXS, half of the software expect the scattering vector to be in 1/nm, while the other half expects them to be in 1/Å. Those units differ by a factor 10 so that the user is easily confused between the two.

The initial idea was to provide 2 hoizontal axis, one in 1/nm, the other in 1/Å ... Then the same story occurred on the vertical axis between absolute scattering intensities and kDa equivalent. This makes then 4 options and as a consequence 3 users out of 4 will be upset by the default display (and are probably not interested in learning how to switch the display).

This is why I believe this issue can easily be addressed by properly labeling the various axis not only with the name of the axe but also the units (this is regardless to the log-scale)

t20100 commented 4 years ago

Displaying the units sounds a good idea, but it is really unclear to me how NeXus supports it.... From the NXData description, it seems only available through the x, y and z dataset which looks to be one of the multiple ways to define the axes....

It sounds reasonable to me to look for a units attribute in each dataset defining the signal and the axes... but that does not seem to be specified in NeXus.

@vasole, how should this be done?

prjemian commented 4 years ago

The @units attribute is standard NeXus (see this GitHub comment) and can be used on any HDF5 dataset. Here's an example from the NeXus manual, plotted with the NeXpy program (showing the units):

writer_1_3.hdf5 : NeXus data file
  Scan:NXentry
    @NX_class = NXentry
    data:NXdata
      @NX_class = NXdata
      @axes = two_theta
      @signal = counts
      @two_theta_indices = 0
      counts:NX_INT32[31] = [1037, 1318, 1704, '...', 1321]
        @units = counts
      two_theta:NX_FLOAT64[31] = [17.92608, 17.92591, 17.92575, '...', 17.92108]
        @units = degrees

Clipboard01

vasole commented 4 years ago

@kif @t20100

I think you have forgotten what is already implemented and already supported in silx :)

Besides the use of the @units, silx view already supported the old @long_name approach.

You just have to run silx view on the file generated by the BasicWriter.py example found at https://manual.nexusformat.org/examples/h5py/index.html

kif commented 4 years ago

Hi Armando, I raised the issue because it was not working as I initially expected ... Thomas neither reminded the issue was already addressed

I just checked, the file built from BasicWriter.py is displayed as expected with silx view but not the files I created for the biosaxs beamline. So the error is somewhere in my code. Maybe because q has the @units attribute but I is still missing it (still unclear, to be discussed with the beamline staff this afternoon which unit they prefer)

Cheers, Jerome

vasole commented 4 years ago

Please take a look. It might be what is actually used for the plotting is the @long_name

kif commented 4 years ago

Please take a look. It might be what is actually used for the plotting is the @long_name

I agree, long_name is used, please see: https://github.com/kif/dahu/blob/master/plugins/bm29/integrate.py#L318

t20100 commented 4 years ago

What about using @long_name if present and else using the dataset name + @units between parenthesis if present.

prjemian commented 4 years ago

Precisely.

loichuder commented 4 months ago

What about using @long_name if present and else using the dataset name + @units between parenthesis if present.

This is what is done in h5web. I can add it to silx as well.

t20100 commented 4 months ago

I can add it to silx as well.

That would be great!

loichuder commented 4 months ago

Any tip on where that should be changed ? :sweat_smile:

t20100 commented 4 months ago

The parsing of Nexus occurs in the silx.io.nxdata.NXdata class:

https://github.com/silx-kit/silx/blob/3ad594b41c44d53fd158495e0fea8d0b708ae014/src/silx/io/nxdata/parse.py#L189-L191 https://github.com/silx-kit/silx/blob/3ad594b41c44d53fd158495e0fea8d0b708ae014/src/silx/io/nxdata/parse.py#L199-L205 https://github.com/silx-kit/silx/blob/3ad594b41c44d53fd158495e0fea8d0b708ae014/src/silx/io/nxdata/parse.py#L448-L454

It is then used in silx.gui.data.DataViews to set the NxData plots that are provided by silx.gui.data.NXdataWidgets.

By changing NxData's signal_name, axis_names,... to also use the @units, the rest should not be affected. This would require to check how those are used to make sure adding a (units) suffix will not be an issue.

An alternative is to support the @units in NxData (e.g., signal_units, axis_units...) and to use this in silx.gui.data.DataViews to set the plots. This as the advantage of not changing the current behavior but I'm not sure it is really needed.