Posted by
Fred Damen on
URL: http://imagej.273.s1.nabble.com/plotwindow-drawPlot-plot-incessant-resizing-tp5022995.html
Greetings,
I have a plugin that plots the statistics of an ROI through the frame
dimension. And replots this information when the Roi is altered. The
trouble is that if you resize the plotwindow and then cause the plot to be
redrawn (plotwindow.drawPlot(plot);) the plotwindow appears to insist upon
resizing the window somewhat asynchronously. Sometimes to the
interactively resized dimensions IRD, but mostly to default dimensions.
So a naive attempt was to query the plotwindow size and set it again after
the drawPlot. This results in the plotwindow more often being resized to
the IRD, alas not always... Figuring that there was one of those race
conditions going on I put in a IJ.wait statement, then the plotwindow
mostly resizes to the IRD, albeit the plotwindow does not get updated
during this wait, and also results in massive flickering. Moving the Roi
with the mouse shows the problem quicker than using the arrow keys, but
within less than 10 redraws the problem happens. Is there a way to get
the plotwindow size not to change on a drawPlot?
This has been happening for the past couple of years on most of the
systems I run this on. Look for the IJ.wait(10); in the below plugin.
Thanks in advance,
Fred
To reproduce:
imp = IJ.createImage("HyperStack", "32-bit grayscale-mode", 128, 128, 1,
1, 10);
imp.setRoi(new OvalRoi(42,52,42,33));
Run this plugin, resize the plotwindow, then move the Roi:
import ij.*;
import ij.plugin.*;
import ij.process.*;
import ij.gui.*;
import ij.util.Tools;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import ij.measure.*;
import java.awt.Rectangle;
/**
This plugin continuously generates Frame-Dimension profile plots as
a selection
is moved or resized through the XY Coordinate Plane.
@author Fred Damen <
[hidden email]>
Version History:
2018-04-01: Created
*/
public class F_Profiler implements PlugIn,
MouseListener,
MouseMotionListener,
MouseWheelListener,
Measurements,
KeyListener,
WindowListener,
ImageListener {
ImagePlus img;
PlotWindow pwin;
public double[] x;
public double[] y;
public double[] ye;
String xLabel;
String yLabel;
public void run(String arg) {
img = IJ.getImage();
int nf = img.getNFrames();
if (nf<2) {
IJ.showMessage("Dynamic F-Dimension Profiler", "This command
requires a HyperStack.");
return;
}
img.getCanvas().addMouseListener(this);
img.getCanvas().addMouseMotionListener(this);
img.getCanvas().addKeyListener(this);
img.getWindow().addMouseWheelListener(this);
img.getWindow().addWindowListener(this);
img.addImageListener(this);
engaged = true;
IJ.showStatus("F-Dimension Profile Engaged: "+img.getTitle());
x = new double[nf];
y = new double[nf];
ye = new double[nf];
String fu = img.getCalibration().getTimeUnit();
try {
ImageStack is = img.getStack();
for(int f=0; f<nf; f++) {
String[] strarr =
is.getSliceLabel(img.getStackIndex(1,1,f+1)).split(",|;",2)[0].split("
= |=| ",2);
xLabel = strarr[0]+(fu!="" ? " ("+fu+")" : "");
x[f] = Float.valueOf(strarr[1]).floatValue();
//for(int ff=0; ff<f; ff++)
// if (x[f] == x[ff])
// throw new Throwable();
//IJ.log("x["+f+"]="+x[f]);
}
}
catch(Throwable e) {
xLabel = "frame"+(fu!="" ? " ("+fu+")" : "");
for(int f=0; f<nf; f++)
x[f] = f;
}
yLabel = img.getTitle()+" ("+img.getCalibration().getValueUnit()+")";
if (!updateProfile())
return;
positionPlotWindow();
}
boolean engaged = false;
void disengage() {
if (!engaged) return;
if (img.getWindow() != null) {
img.getCanvas().removeMouseListener(this);
img.getCanvas().removeMouseMotionListener(this);
img.getCanvas().removeKeyListener(this);
img.getWindow().removeMouseWheelListener(this);
img.getWindow().removeWindowListener(this);
img.removeImageListener(this);
}
pwin = null;
engaged = false;
IJ.showStatus("F-Dimension Profile Disengaged");
}
boolean updateProfile() {
Roi roi = img.getRoi();
if (img == null || roi == null) {
IJ.showStatus("Frame-Dimension Profiles running but nothing to
do");
return true;
}
if ((pwin != null) && (!pwin.isVisible())) {
IJ.log("F_Profiler: should not have reached here '"+pwin+"'");
engaged = true;
disengage();
return false;
}
int nf = img.getNFrames();
int cs = img.getZ();
double[] yM = new double[nf];
double[] ym = new double[nf];
double[] ys = new double[nf];
ImageStack is = img.getStack();
Calibration cal = img.getCalibration();
for(int f=0; f<nf; f++) {
ImageProcessor ip = is.getProcessor(img.getStackIndex(1,cs,f+1));
ip.setRoi(roi);
ImageStatistics stats = ImageStatistics.getStatistics(ip,
MEAN+STD_DEV+MIN_MAX+MEDIAN, cal);
y[f] = stats.mean;
ye[f] = stats.stdDev;
yM[f] = stats.max;
ym[f] = stats.min;
ys[f] = stats.median;
}
Plot plot = new Plot("Frame Profile ("+img.getTitle()+")", xLabel, yLabel);
plot.setFont(new Font("Comic Sans MS", Font.PLAIN, 20));
plot.setXLabelFont(new Font("Comic Sans MS", Font.PLAIN, 24));
plot.setYLabelFont(new Font("Comic Sans MS", Font.PLAIN, 24));
plot.setColor(Color.blue);
plot.setLineWidth(1);
plot.addPoints(x,y,ye,Plot.X);
plot.setColor(Color.red);
plot.setLineWidth(4);
plot.addPoints(x,y,Plot.X);
plot.setColor(Color.green);
plot.setLineWidth(2);
plot.addPoints(x,ym,Plot.BOX);
plot.addPoints(x,yM,Plot.BOX);
plot.setColor(Color.black);
plot.addPoints(x,ys,Plot.CIRCLE);
plot.setLegend("stddev\nmean\nmax\nmin\nmedian",Plot.AUTO_POSITION);
if (pwin==null) {
pwin = plot.show();
pwin.addWindowListener(this);
}
else {
Dimension s = pwin.getSize();
pwin.drawPlot(plot);
pwin.setSize(s);
IJ.wait(10);
pwin.setSize(s);
}
plot.setLimitsToFit(true);
return true;
}
void positionPlotWindow() {
IJ.wait(500);
if (pwin==null || img==null) return;
ImageWindow iwin = img.getWindow();
if (iwin==null) return;
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
Dimension plotSize = pwin.getSize();
Dimension imageSize = iwin.getSize();
if (plotSize.width==0 || imageSize.width==0) return;
Point imageLoc = iwin.getLocation();
int w = imageLoc.x+imageSize.width+10;
if (w+plotSize.width>screen.width)
w = screen.width-plotSize.width;
pwin.setLocation(w, imageLoc.y);
iwin.toFront();
}
public void mousePressed(MouseEvent e) {
Roi roi = img.getRoi();
int ix,iy;
if (roi == null) {
Point here = img.getCanvas().getCursorLoc();
ix = here.x;
iy = here.y;
}
else if (roi.getType() == Roi.POINT) {
Rectangle bounds = roi.getBounds();
ix = bounds.x;
iy = bounds.y;
}
else {
updateProfile();
return;
}
int nf = img.getNFrames();
int cs = img.getZ();
ImageStack is = img.getStack();
for(int f=0; f<nf; f++) {
ImageProcessor ip = is.getProcessor(img.getStackIndex(1,cs,f+1));
y[f] = ip.getPixelValue(ix, iy);
ye[f] = 0;
}
Plot plot = new Plot("Frame Profile ("+img.getTitle()+")", xLabel, yLabel);
plot.setFont(new Font("Comic Sans MS", Font.PLAIN, 20));
plot.setXLabelFont(new Font("Comic Sans MS", Font.PLAIN, 24));
plot.setYLabelFont(new Font("Comic Sans MS", Font.PLAIN, 24));
plot.setColor(Color.blue);
plot.setLineWidth(4);
Calibration cal = img.getCalibration();
plot.setJustification(Plot.RIGHT);
plot.addLabel(0.99,0.99,String.format("%.2f(%d), %.2f(%d), (%d)",
cal.getX(ix),ix,cal.getY(iy),iy,img.getT()));
plot.addPoints(x,y,ye,Plot.X);
if (pwin==null) {
pwin = plot.show();
pwin.addWindowListener(this);
}
else {
Dimension s = pwin.getSize();
pwin.drawPlot(plot);
pwin.setSize(s);
}
plot.setLimitsToFit(true);;
}
public void mouseDragged(MouseEvent e) { updateProfile(); }
public void keyReleased(KeyEvent e) { updateProfile(); }
public void keyPressed(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}
public void mouseWheelMoved(MouseWheelEvent e) { /* updateProfile(); */ }
public void windowActivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) { disengage();}
public void windowClosing(WindowEvent e) { disengage();}
public void windowDeactivated(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
public void imageClosed(ImagePlus imp) {}
public void imageOpened(ImagePlus imp) {}
public void imageUpdated(ImagePlus imp) { /* if (imp==img)
updateProfile(); */}
}
--
ImageJ mailing list:
http://imagej.nih.gov/ij/list.html