Add data labels within the Plot lists

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Add data labels within the Plot lists

CARL Philippe (LBP)
Dear all (probably mostly Michael and/or Wayne),
What do you think about adding labels for the data within the plots so that
when you list the plot data there is the possibility to not anymore read: X0
Y0, Y1,… but instead attributed data names.
This could for example be done by extending the "Plot.add(type, xValues,
yValues)" method by something like "Plot.add(type, xValues, yValues, "Data
name")".
And a method "Plot.setLegend()" could as well be added.
Indeed, in the case there is only 1 to 3 data sets the way the code is now
is in not an issue, but with more data it becomes easily difficult to
understand and interpret the listed data.
Also do you see any issue which could limit or prohibit such an update?
If not I could generate the needed code and submit it to you guys for
validation.
Bien cordialement,
Philippe

Philippe CARL
Laboratoire de Bioimagerie et Pathologies
UMR 7021 CNRS - Université de Strasbourg
Faculté de Pharmacie
74 route du Rhin
67401 ILLKIRCH
Tel : +33(0)3 68 85 41 84

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Add data labels within the Plot lists

Michael Schmid
Hi Philippe,

yes, I agree it would be nice to have nicer headings when listing data!
Before doing this, there are a few issues to think about:

(1) Plot.getResultsTable() is a public method; so there will be plugins
and JavaScript/Python/etc. code that rely on the current column header
names. We have to keep it compatible, so it has to be a new method like
   Plot.getResultsTable(boolean writeFirstXColumn,
            boolean useVariableLabelsAsColumnHeadings)
and the current getResultsTable(boolean writeFirstXColumn) has to be
mapped to
   Plot.getResultsTable(writeFirstXColumn, false)

(2) Up to now, ResultsTable headings are single words that follow
variable name syntax. The "Apply Macro" of ResultsTables can work around
this limitation. We have to check whether having arbitrary names can
cause problems elsewhere.

@Wayne: are you aware of any limitation in this respect?

(3) We have to take care of duplicate labels in the legend (which is
allowed). Column headings in a ResultsTable must be unique.

(4) I guess it would be best to have the x name from the x axis label
and the y name from the legend (name of the data set), but what to do in
case of multiple x columns? "x_datasetName"?

(5) Plot.add(type, xValues, yValues, datasetName) :
In Java, we have already
   addPoints(float[] xValues, float[] yValues, float[] yErrorBars, int
shape, String label)
where "label" is the name of the data set (it will go into the legend).

In Plot.java, we have more than half a dozen other methods to add data
(different data formats float[], double[], ArrayList; without error
bars, without x values, String or integer for the shape=symbol).
It would be a bit much to duplicate them all, adding versions with a label.
I think it would be more economical to have something like
setLastDataSetLabel(String label).
For adding the macro function, we would need to add to Plot.java only
one more:
   Plot.add(String type, double[] xvalues, double[] yvalues, String labels)

--

The macro language already has a function
   Plot.setLegend("label1\tlabel2...", "options")
which is translated to Java
   Plot.addLegend(String labels, String options)
and there is the Java method
   Plot.setLegend(String labels, int flags)
where flags=0 just adds the labels (tab- or linefeed-delimited) without
showing the legend.

Is your suggestion of Plot.setLegend() meant as a macro function to hide
the legend? We could simply add a "hide" or "off" keyword to the options of
   Plot.addLegend(String labels, String options)
and the "hide" or "off" would translate to flags=0.


Best,

Michael
________________________________________________________________

On 14.03.19 14:14, Philippe CARL wrote:

> Dear all (probably mostly Michael and/or Wayne),
> What do you think about adding labels for the data within the plots so that
> when you list the plot data there is the possibility to not anymore read: X0
> Y0, Y1,… but instead attributed data names.
> This could for example be done by extending the "Plot.add(type, xValues,
> yValues)" method by something like "Plot.add(type, xValues, yValues, "Data
> name")".
> And a method "Plot.setLegend()" could as well be added.
> Indeed, in the case there is only 1 to 3 data sets the way the code is now
> is in not an issue, but with more data it becomes easily difficult to
> understand and interpret the listed data.
> Also do you see any issue which could limit or prohibit such an update?
> If not I could generate the needed code and submit it to you guys for
> validation.
> Bien cordialement,
> Philippe
>
> Philippe CARL
> Laboratoire de Bioimagerie et Pathologies
> UMR 7021 CNRS - Université de Strasbourg
> Faculté de Pharmacie
> 74 route du Rhin
> 67401 ILLKIRCH
> Tel : +33(0)3 68 85 41 84

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Add data labels within the Plot lists

Wayne Rasband-2
> On Mar 14, 2019, at 10:10 AM, Michael Schmid <[hidden email]> wrote:
>
> Hi Philippe,
>
> yes, I agree it would be nice to have nicer headings when listing data!
> Before doing this, there are a few issues to think about:
>
> (1) Plot.getResultsTable() is a public method; so there will be plugins and JavaScript/Python/etc. code that rely on the current column header names. We have to keep it compatible, so it has to be a new method like
>  Plot.getResultsTable(boolean writeFirstXColumn,
>           boolean useVariableLabelsAsColumnHeadings)
> and the current getResultsTable(boolean writeFirstXColumn) has to be mapped to
>  Plot.getResultsTable(writeFirstXColumn, false)

It would be better to have a new Plot.getResultsTableWithLabels() method that avoids mysterious boolean arguments that make the code hard to understand.

> (2) Up to now, ResultsTable headings are single words that follow variable name syntax. The "Apply Macro" of ResultsTables can work around this limitation. We have to check whether having arbitrary names can cause problems elsewhere.
>
> @Wayne: are you aware of any limitation in this respect?

Labels with spaces and special characters might be a problem. Plot.getResultsTableWithLabels() could replace them with underscores.

> (3) We have to take care of duplicate labels in the legend (which is allowed). Column headings in a ResultsTable must be unique.
>
> (4) I guess it would be best to have the x name from the x axis label and the y name from the legend (name of the data set), but what to do in case of multiple x columns? "x_datasetName"?
>
> (5) Plot.add(type, xValues, yValues, datasetName) :
> In Java, we have already
>  addPoints(float[] xValues, float[] yValues, float[] yErrorBars, int shape, String label)
> where "label" is the name of the data set (it will go into the legend).

It would be best to have a single new method like Plot.setLabel(label) that sets the label of the last object added, and not add an string argument to the many existing methods that draw objects.

-wayne

> In Plot.java, we have more than half a dozen other methods to add data (different data formats float[], double[], ArrayList; without error bars, without x values, String or integer for the shape=symbol).
> It would be a bit much to duplicate them all, adding versions with a label.
> I think it would be more economical to have something like setLastDataSetLabel(String label).
> For adding the macro function, we would need to add to Plot.java only one more:
>  Plot.add(String type, double[] xvalues, double[] yvalues, String labels)
>
> --
>
> The macro language already has a function
>  Plot.setLegend("label1\tlabel2...", "options")
> which is translated to Java
>  Plot.addLegend(String labels, String options)
> and there is the Java method
>  Plot.setLegend(String labels, int flags)
> where flags=0 just adds the labels (tab- or linefeed-delimited) without showing the legend.
>
> Is your suggestion of Plot.setLegend() meant as a macro function to hide the legend? We could simply add a "hide" or "off" keyword to the options of
>  Plot.addLegend(String labels, String options)
> and the "hide" or "off" would translate to flags=0.
>
>
> Best,
>
> Michael
> ________________________________________________________________
>
> On 14.03.19 14:14, Philippe CARL wrote:
>> Dear all (probably mostly Michael and/or Wayne),
>> What do you think about adding labels for the data within the plots so that
>> when you list the plot data there is the possibility to not anymore read: X0
>> Y0, Y1,… but instead attributed data names.
>> This could for example be done by extending the "Plot.add(type, xValues,
>> yValues)" method by something like "Plot.add(type, xValues, yValues, "Data
>> name")".
>> And a method "Plot.setLegend()" could as well be added.
>> Indeed, in the case there is only 1 to 3 data sets the way the code is now
>> is in not an issue, but with more data it becomes easily difficult to
>> understand and interpret the listed data.
>> Also do you see any issue which could limit or prohibit such an update?
>> If not I could generate the needed code and submit it to you guys for
>> validation.
>> Bien cordialement,
>> Philippe
>> Philippe CARL

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Add data labels within the Plot lists

Fred Damen
In reply to this post by CARL Philippe (LBP)
Greetings,

I find this useful, as the only time I click 'List' on the plot window is to
debug the plot.  There are cases in which a plot point is listed with a blank
y-value.  I assume this is + or - infinity as I believe that the only other
non-printable number in NaN.  It would be useful for debugging to have the
value explicitly stated, even if on an array that is short.

Thanks,

Fred

On Thu, March 14, 2019 8:14 am, Philippe CARL wrote:

> Dear all (probably mostly Michael and/or Wayne),
> What do you think about adding labels for the data within the plots so that
> when you list the plot data there is the possibility to not anymore read: X0
> Y0, Y1,… but instead attributed data names.
> This could for example be done by extending the "Plot.add(type, xValues,
> yValues)" method by something like "Plot.add(type, xValues, yValues, "Data
> name")".
> And a method "Plot.setLegend()" could as well be added.
> Indeed, in the case there is only 1 to 3 data sets the way the code is now
> is in not an issue, but with more data it becomes easily difficult to
> understand and interpret the listed data.
> Also do you see any issue which could limit or prohibit such an update?
> If not I could generate the needed code and submit it to you guys for
> validation.
> Bien cordialement,
> Philippe
>
> Philippe CARL
> Laboratoire de Bioimagerie et Pathologies
> UMR 7021 CNRS - Université de Strasbourg
> Faculté de Pharmacie
> 74 route du Rhin
> 67401 ILLKIRCH
> Tel : +33(0)3 68 85 41 84
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Add data labels within the Plot lists

Michael Schmid
Hi Fred,

The tables created by Plots have blank entries at the end if the data
array is shorter than the length of the table.
[Technically, these are actually empty Strings, which have a numerical
"NaN" value hidden behind them.  Any numerical functions such as
Table.get and "Apply Macro" use the NaN; subsequent plotting of the data
in the table simply omits the NaN points].

You get these empty cells when you plot arrays of different length.
Plots created by Analyze>Tools>Curve Fitting are a typical example.


ResultsTables show NaN as "NaN" and +/-Infinity as "Infinity" or
"+Infinity".
Try this macro:

   Table.create();
   Table.set("a", 0, NaN);
   Table.set("b", 0, 1e200*1e200);
   Table.set("c", 0, -1e200*1e200);
   Table.update;

This is also true for plots (I tried a curve fit creating infinity
values and listing the data).


Michael
________________________________________________________________
On 14.03.19 19:06, Fred Damen wrote:

> Greetings,
>
> I find this useful, as the only time I click 'List' on the plot window is to
> debug the plot.  There are cases in which a plot point is listed with a blank
> y-value.  I assume this is + or - infinity as I believe that the only other
> non-printable number in NaN.  It would be useful for debugging to have the
> value explicitly stated, even if on an array that is short.
>
> Thanks,
>
> Fred
>
> On Thu, March 14, 2019 8:14 am, Philippe CARL wrote:
>> Dear all (probably mostly Michael and/or Wayne),
>> What do you think about adding labels for the data within the plots so that
>> when you list the plot data there is the possibility to not anymore read: X0
>> Y0, Y1,… but instead attributed data names.
>> This could for example be done by extending the "Plot.add(type, xValues,
>> yValues)" method by something like "Plot.add(type, xValues, yValues, "Data
>> name")".
>> And a method "Plot.setLegend()" could as well be added.
>> Indeed, in the case there is only 1 to 3 data sets the way the code is now
>> is in not an issue, but with more data it becomes easily difficult to
>> understand and interpret the listed data.
>> Also do you see any issue which could limit or prohibit such an update?
>> If not I could generate the needed code and submit it to you guys for
>> validation.
>> Bien cordialement,
>> Philippe
>>
>> Philippe CARL
>> Laboratoire de Bioimagerie et Pathologies
>> UMR 7021 CNRS - Université de Strasbourg
>> Faculté de Pharmacie
>> 74 route du Rhin
>> 67401 ILLKIRCH
>> Tel : +33(0)3 68 85 41 84
>>
>> --
>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Add data labels within the Plot lists

Fred Damen
Greetings,

Thanks for the reply, but these are not the case that I was referring to.
What I was referring to was within a list of Xn,Yn values one, or more, of the
Yn cells, that have values in the corresponding Xn cells, have blank cells,
i.e.,

"X0","Y0"
0,1
1,""
2,5

Cases in which are NaN did/do get displayed as "NaN".  As my y-values deal
with taking the log of fractional numbers, I just assumed that these blank
values where negative infinity and kept on debugging.  I just wrote a test
plugin and the infinity values get displayed as you pointed out. So there is
some other value that is getting displayed as a blank.  When I see the issue
again, i will try and determine what the value is...

Thanks,

Fred


On Thu, March 14, 2019 3:00 pm, Michael Schmid wrote:

> Hi Fred,
>
> The tables created by Plots have blank entries at the end if the data
> array is shorter than the length of the table.
> [Technically, these are actually empty Strings, which have a numerical
> "NaN" value hidden behind them.  Any numerical functions such as
> Table.get and "Apply Macro" use the NaN; subsequent plotting of the data
> in the table simply omits the NaN points].
>
> You get these empty cells when you plot arrays of different length.
> Plots created by Analyze>Tools>Curve Fitting are a typical example.
>
>
> ResultsTables show NaN as "NaN" and +/-Infinity as "Infinity" or
> "+Infinity".
> Try this macro:
>
>    Table.create();
>    Table.set("a", 0, NaN);
>    Table.set("b", 0, 1e200*1e200);
>    Table.set("c", 0, -1e200*1e200);
>    Table.update;
>
> This is also true for plots (I tried a curve fit creating infinity
> values and listing the data).
>
>
> Michael
> ________________________________________________________________
> On 14.03.19 19:06, Fred Damen wrote:
>> Greetings,
>>
>> I find this useful, as the only time I click 'List' on the plot window is to
>> debug the plot.  There are cases in which a plot point is listed with a
>> blank
>> y-value.  I assume this is + or - infinity as I believe that the only other
>> non-printable number in NaN.  It would be useful for debugging to have the
>> value explicitly stated, even if on an array that is short.
>>
>> Thanks,
>>
>> Fred
>>
>> On Thu, March 14, 2019 8:14 am, Philippe CARL wrote:
>>> Dear all (probably mostly Michael and/or Wayne),
>>> What do you think about adding labels for the data within the plots so that
>>> when you list the plot data there is the possibility to not anymore read:
>>> X0
>>> Y0, Y1,… but instead attributed data names.
>>> This could for example be done by extending the "Plot.add(type, xValues,
>>> yValues)" method by something like "Plot.add(type, xValues, yValues, "Data
>>> name")".
>>> And a method "Plot.setLegend()" could as well be added.
>>> Indeed, in the case there is only 1 to 3 data sets the way the code is now
>>> is in not an issue, but with more data it becomes easily difficult to
>>> understand and interpret the listed data.
>>> Also do you see any issue which could limit or prohibit such an update?
>>> If not I could generate the needed code and submit it to you guys for
>>> validation.
>>> Bien cordialement,
>>> Philippe
>>>
>>> Philippe CARL
>>> Laboratoire de Bioimagerie et Pathologies
>>> UMR 7021 CNRS - Université de Strasbourg
>>> Faculté de Pharmacie
>>> 74 route du Rhin
>>> 67401 ILLKIRCH
>>> Tel : +33(0)3 68 85 41 84
>>>
>>> --
>>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>>
>>
>> --
>> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>>
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
Reply | Threaded
Open this post in threaded view
|

Re: Add data labels within the Plot lists

CARL Philippe (LBP)
In reply to this post by Wayne Rasband-2
Dear everybody, but I guess mostly Wayne and Michael (should we rather leave the postponing of this discussion private between us until release?),
I tried to play a little bit around with the discussed implementation following your recommendations.

Thus for:

> It would be best to have a single new method like Plot.setLabel(label) that sets the label of the last object added,
> and not add an string argument to the many existing methods that draw objects.

I added the following code:
                else if (name.equals("setLabel")) {
                        currentPlot.setPlotObjectLabel(currentPlot.getNumPlotObjects()-1, getStringArg());
                        return Double.NaN;
                }
within the "double doPlot()" method of the ij.macro.Functions.java file.
Which code seems to be working correctly.

But for:
> It would be better to have a new Plot.getResultsTableWithLabels() method that avoids mysterious boolean arguments
> that make the code hard to understand.

I didn't really understand what you meant.
Would you like to have both getResultsTable() and getResultsTableWithLabels() methods within the ij.gui.Plot.java file?
And one should there be used either one of both? How to choose between the two methods?

In parallel, I did something quite simple, i.e. I just added the line
                        if(plotObject.label != null) label = plotObject.label;
before the line
                        headings.add(label);
in the following code:
                if (writeY) {
                        String label = plotObject.type == PlotObject.ARROWS ? "YStart" : "Y";
                        if (multipleSets) label += dataSetNumber;
                        if (dataSetNumber==0 && plotObject.type!=PlotObject.ARROWS) {
                                String plotYLabel = getLabel('y');
                                if (plotYLabel!=null && plotYLabel.startsWith(" ") && plotYLabel.endsWith(" "))
                                        label = plotYLabel.substring(1,plotYLabel.length()-1);
                        }
                        headings.add(label);
                        data.add(plotObject.yValues);
                }
of the "void addToLists(ArrayList<String> headings, ArrayList<float[]>data, PlotObject plotObject,
                        int dataSetNumber, boolean writeX, boolean writeY, boolean multipleSets)"
method of the ij.gui.Plot.java file. Compiled it and tried it on the following macro code:
https://imagej.nih.gov/ij/macros/examples/Example_Plot.txt
and this was already doing the expected job.

And with this modification, on the question:
> Labels with spaces and special characters might be a problem. Plot.getResultsTableWithLabels() could replace them with underscores.
The answer is "no" : it is correctly printing the spaces with the labels.
I even pushed it further by using the "More>Legend..." tool of the plot window and modifyed the legend text.
And the following listed data were correctly showing the corrected legend inputs.

Thus what are the potential issues of the simple update I described higher?
I thank you very much in advance for your lightings.
My best regards,
Philippe

Philippe CARL
Laboratoire de Bioimagerie et Pathologies
UMR 7021 CNRS - Université de Strasbourg
Faculté de Pharmacie
74 route du Rhin
67401 ILLKIRCH
Tel : +33(0)3 68 85 41 84


-----Message d'origine-----
De : ImageJ Interest Group [mailto:[hidden email]] De la part de Wayne Rasband
Envoyé : jeudi 14 mars 2019 18:02
À : [hidden email]
Objet : Re: Add data labels within the Plot lists

> On Mar 14, 2019, at 10:10 AM, Michael Schmid <[hidden email]> wrote:
>
> Hi Philippe,
>
> yes, I agree it would be nice to have nicer headings when listing data!
> Before doing this, there are a few issues to think about:
>
> (1) Plot.getResultsTable() is a public method; so there will be plugins and JavaScript/Python/etc. code that rely on the current column header names. We have to keep it compatible, so it has to be a new method like
>  Plot.getResultsTable(boolean writeFirstXColumn,
>           boolean useVariableLabelsAsColumnHeadings)
> and the current getResultsTable(boolean writeFirstXColumn) has to be mapped to
>  Plot.getResultsTable(writeFirstXColumn, false)

It would be better to have a new Plot.getResultsTableWithLabels() method that avoids mysterious boolean arguments that make the code hard to understand.

> (2) Up to now, ResultsTable headings are single words that follow variable name syntax. The "Apply Macro" of ResultsTables can work around this limitation. We have to check whether having arbitrary names can cause problems elsewhere.
>
> @Wayne: are you aware of any limitation in this respect?

Labels with spaces and special characters might be a problem. Plot.getResultsTableWithLabels() could replace them with underscores.

> (3) We have to take care of duplicate labels in the legend (which is allowed). Column headings in a ResultsTable must be unique.
>
> (4) I guess it would be best to have the x name from the x axis label and the y name from the legend (name of the data set), but what to do in case of multiple x columns? "x_datasetName"?
>
> (5) Plot.add(type, xValues, yValues, datasetName) :
> In Java, we have already
>  addPoints(float[] xValues, float[] yValues, float[] yErrorBars, int shape, String label)
> where "label" is the name of the data set (it will go into the legend).

It would be best to have a single new method like Plot.setLabel(label) that sets the label of the last object added, and not add an string argument to the many existing methods that draw objects.

-wayne

> In Plot.java, we have more than half a dozen other methods to add data (different data formats float[], double[], ArrayList; without error bars, without x values, String or integer for the shape=symbol).
> It would be a bit much to duplicate them all, adding versions with a label.
> I think it would be more economical to have something like setLastDataSetLabel(String label).
> For adding the macro function, we would need to add to Plot.java only one more:
>  Plot.add(String type, double[] xvalues, double[] yvalues, String labels)
>
> --
>
> The macro language already has a function
>  Plot.setLegend("label1\tlabel2...", "options")
> which is translated to Java
>  Plot.addLegend(String labels, String options)
> and there is the Java method
>  Plot.setLegend(String labels, int flags)
> where flags=0 just adds the labels (tab- or linefeed-delimited) without showing the legend.
>
> Is your suggestion of Plot.setLegend() meant as a macro function to hide the legend? We could simply add a "hide" or "off" keyword to the options of
>  Plot.addLegend(String labels, String options)
> and the "hide" or "off" would translate to flags=0.
>
>
> Best,
>
> Michael
> ________________________________________________________________
>
> On 14.03.19 14:14, Philippe CARL wrote:
>> Dear all (probably mostly Michael and/or Wayne),
>> What do you think about adding labels for the data within the plots so that
>> when you list the plot data there is the possibility to not anymore read: X0
>> Y0, Y1,… but instead attributed data names.
>> This could for example be done by extending the "Plot.add(type, xValues,
>> yValues)" method by something like "Plot.add(type, xValues, yValues, "Data
>> name")".
>> And a method "Plot.setLegend()" could as well be added.
>> Indeed, in the case there is only 1 to 3 data sets the way the code is now
>> is in not an issue, but with more data it becomes easily difficult to
>> understand and interpret the listed data.
>> Also do you see any issue which could limit or prohibit such an update?
>> If not I could generate the needed code and submit it to you guys for
>> validation.
>> Bien cordialement,
>> Philippe
>> Philippe CARL

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html

--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html