Saving Results from "Plot Values" into Arrays in ImageJ Macro

results
array
macro
Tags: #<Tag:0x00007fb8828cfb80> #<Tag:0x00007fb8828cf8d8> #<Tag:0x00007fb8828cf5e0>

#1

Hello All,

So I have this square wave plot which I have generated from a binary image (first image). From this I use the BAR toolbar -> Data Analysis -> Find Peaks. That returns me the same square plot with the minimum and maximums labeled along with a table called “Plot Values” (following two images).

The BAR installation instructions can be found at: https://imagej.net/BAR#Installation

My only question right now is How do I save the values in Columns X1 and X2 in arrays called “X1” and “X2” using an ImageJ macro? Because I need this data to perform lots of different data analysis, And I have 100s of images to work with so I want to automate this process so that I do not need to keep manually copying pasting data from the data table into an excel file. If anyone is able to help me how to get these values stored in arrays, I am good from there. Because then I can just directly do all my analysis in ImageJ macro and print only the final results my prof needs to an excel file, making the process efficient and simple and clean.

Thanks!
Abi


#2

Only 8 h ago the solution was posted here:
http://forum.imagej.net/t/copy-log-content-to-clipboard/6590/6?u=herbie

IJ.renameResults("Plot Values","Results");
// now loop over all row indices
x_1[rowIndex] = getResult("X1", rowIndex);
x_2[rowIndex] = getResult("X2", rowIndex);
// and tidy up
IJ.renameResults("Results","Plot Values");

Regards

Herbie


#3

Thanks for the note of making it a Results table in order to extract info. I had missed that part. But then this is where it falls apart. IJ.renameResults gives me an error of undefined and so I did

  selectWindow("Plot Values");
  rename("Results");
// now loop over all row indices
x_1 = getResult(“X1”, rowIndex);
x_2 = getResult(“X2”, rowIndex);
// and tidy up
selectWindow("Results");
rename("Plot Values");

Of course this code falls apart because rowIndex is undefined …

The next logical question I have is, I have different number of row indices for each such graph and table. How do I loop through all the different rowIndices without having to specify them manually? Again its for 100s of images. And each time the rowIndex will be different, even within the same image if I am analysing it.

Is there any way to directly import the entire column into an array? I tried playing around with nResults, but that gave me a number that does not correspond to the number of results in the table at all… All I want is just those two columns in arrays. Each table will have a different number of rows for X1 and X2 so I want to be able to account for that automatically as well.


#4

Please learn how to code macros which is explained here:
https://imagej.nih.gov/ij/developer/macro/macros.html
https://imagej.nih.gov/ij/developer/macro/functions.html

Regards

Herbie


#5

Herbie, I understand you are getting frustrated with me, but I have already exhausted those resources. I know how to code Macros. Unfortunately I see a major flaw in ImageJ macro commands for not even being able to extract a data column… That’s the issue I am having. That is the only reason I have asked here.


#6
l = getWidth();
//---- VARIABLE: Depends how many lines you want -----//
k = 6;
// ---------------------------------------------------//
h = getHeight()/k;

for (i = 0; i < k; i++){
	selectWindow("binary");
	makeLine(0,h*i+h/2,l,h*i+h/2,1);
	// you can start measuring from any altitude you want by modifying the "+h/2" part. 
	//If you want to start at altitude of "0", simply delete the "+" portion
	run("Plot Profile");
run("Find Peaks", "min._peak_amplitude=254.99 min._peak_distance=0 min._value=[] max._value=[]");
selectWindow("Peaks in Plot of binary");
rename("Peaks" + (i+1));
//close("Plot of binary");
//close("Plot Values");
	selectWindow("binary");
	drawLine(0,h*i+h/2,l,h*i+h/2);
	//close("Peaks in Plot of binary");
}
//close("binary");

This is the code that starts with my binary image and generates all the plots and data tables. The ONLY THING I need help with is saving two columns of data into arrays, where these two columns unfortunately have variable row numbers


#7

[…] I have already exhausted those resource.

Those or yours?

If you have your data in a table named “Results” that is frontmost you must loop over the row indices:

// define the array
myArray = newArray(nResults);
// loop
for ( i=0; i<nResults; i++ ) { 
	myArray[i] = getResult("Column name", i);
}
// look at the array
Array.show(myArray);

HTH

Herbie

PS:
It might still be of interest that in your earlier thread I’ve posted a macro that does all you need:
Mean object length for each scan line.
Did you ever try?


#8

I did try your code from the previous thread and it gave me the mean object length for each scan line as you correctly said and gave the code for, but that is not what I am after. I need individual lengths, which I know now how to get manually from the table “Plot Values”. The only problem is I don’t want to keep saving data manually from 100 tables for 100s of images, since each horizontal line I draw in the image generates a different table with X1 and X2 having different numbers of rows. I am after exactly what I asked in this thread actually as my first post. If you run the code on my original binary image (title of the binary image window would simply be “binary”:

l = getWidth();
h = getHeight()/6;
selectWindow("binary");
makeLine(0,h/2,l,h/2,1);
// you can start measuring from any altitude you want by modifying the "+h/2" part. 
//If you want to start at altitude of "0", simply delete the "+" portion
run("Plot Profile");
run("Find Peaks", "min._peak_amplitude=254.99 min._peak_distance=0 min._value=[] max._value

And try out the BAR toolbar, you will know exactly what I am talking about. The Table “Plot Values” CANNOT be renamed as “Results”… you will see that it renames the binary image as “Results” instead and leaves the “Plot Values” as “Plot Values”. The command "IJ.renameResults(“Plot Values” , “Results”); gives an error.

If you or anyone else can help me just get those two columns I have asked for into arrays that would be the most wonderful help. I wish there was a command where I could import the entire column… because the command getResult(“Column”, row); ONLY gives one data point which is not what I am after. I need the entire column.

PS: nResults gives me a random value which I have no idea what it is specifying


#9

[…] because the command getResult(“Column”, row); ONLY gives one data point which is not what I am after.

You have to loop over all rows!
See my previous post that gives you the code.

Regards

Herbie


#10

And that is what I am trying to figure out how to get the values of from within the macro… I have to specify the number of rows manually each time, which I do not want to do… Since I have 100x100 tables I will be dealing with (100 tables per image, 100 images)


#11

The number is in “nResults”. Please run the above code of mine!


#12

Please run my code on the binary image to understand what I am talking about. I think it will make more sense then. nResults gives me a meaningless number to which I have no idea what it is being attributed to


#13

nResults is highly meaningful and it is decribed here:
https://imagej.nih.gov/ij/developer/macro/functions.html

   // define the array
    myArray = newArray(nResults);
    // loop
    for ( i=0; i<nResults; i++ ) { 
    	myArray[i] = getResult("Column name", i);
    }
    // look at the array
    Array.show(myArray);

#14

simply print nResults from the table I get… Then you will see what I am talking about…


#15

Again I’m out.

Herbie


#16

That is because you are not running my code and understanding my code and problem


#17

Anyone else out there willing to help… seriously?


#18

what does nResults = 64 for a table with 6 columns and many values mean to you?


#19

Seriously:

//example macro that shows how to get data columns from the Results table
run("Set Measurements...", "center redirect=None decimal=3");
run("Blobs (25K)");
setAutoThreshold("Default");
setOption("BlackBackground", true);
run("Convert to Mask");
run("Analyze Particles...", "display");
// define the arrays to which the data is copied
myArray_1 = newArray(nResults);
myArray_2 = newArray(nResults);
// loop the table rows
for ( i=0; i<nResults; i++ ) { 
    	myArray_1[i] = getResult("XM", i);
	myArray_2[i] = getResult("YM", i);
}
//close("Results");
// have a look at the arrays
Array.print(myArray_1);
Array.print(myArray_2);

Herbie


#20

@Abi,

It certainly seems frustrating at the moment, and after playing around with your and Herbie’s code for a while I can’t find a way to directly get the info you want either.

As an alternative, perhaps you could just save the data files and then read them back in, in order to create the arrays you need.

Possibly, you could get the number of rows of data in your columns of interest by checking for NaNs as you loop through the rows.

Functions used might include File.openAsString (followed by split) and File.append.

Hope this helps.