Re: plotwindow.drawPlot(plot) incessant resizing

Posted by Fred Damen on
URL: http://imagej.273.s1.nabble.com/plotwindow-drawPlot-plot-incessant-resizing-tp5022995p5023004.html

Greetings Michael,

A mute point now, but, to reproduce, create hyperstack, create roi, start
plugin, resize plotwindow, move the roi a dozen times.

The plot.userTemplate works great; aggravation level plummets...

For the PlotMaker example that you gave, what instigates the drawing of
the next plot. I assume that getPlot is called by PlotWindow, but how to
setup the trigger?

For the RoiListener, who calls roiModified, i.e., static or instance?  I
found out the hard way that the ImageListener methods were called when any
/ all imageplus objects were affected; ugly race conditions when trying to
close a list of images... use WindowListener instead...

The attached plugin serves the same general purpose as the ProfilePlot,
albeit in the frame direction.  If you collected the same volume (stack of
slices) repeatedly and you wanted to know if / how the signal changes
through the repeats.

Thanks,

Fred

On Mon, March 2, 2020 4:32 am, Michael Schmid wrote:

> Hi Fred,
>
> there was no problem when I tried it, it works also after resizing the
> plot.
> Nevertheless, there is an elegant way to make the plot inherit the size
> of the previous one shown in the same PlotWindow:
>
>    plot.useTemplate(previousPlot, Plot.COPY_SIZE);
>
> You can also have it inherit other properties, such as the legend, axis
> labels, style, or curves added by the user (who had used the buttons at
> the bottom of the plot).
> Just use a bitwise OR or the sum of the following flags:
>
> COPY_SIZE    Flag for copying from a template: copy plot size
> COPY_LABELS  Flag for copying from a template: copy style & text of axis
> COPY_LEGEND  Flag for copying from a template: copy legend
> COPY_AXIS_STYLE  Flag for copying from a template: copy axis style
> COPY_CONTENTS_STYLE  Flag for copying from a template: copy contents
> COPY_EXTRA_OBJECTS Flag for copying PlotObjects (curves...) from a
> template if the template has more PlotObjects than the Plot to copy to.
>
>
> In your case (I did not really try to understand your plugin), it seems
> that the plot is supposed to react on changes of the Roi? Then there
> might be an easier option, just implement the PlotMaker Interface.
> The first 40 lines of the Profiler provide an example how to do this:
>
>    https://github.com/imagej/imagej1/blob/master/ij/plugin/Profiler.java
>
> If a PlotMaker is no option for you, there is also a RoiListener
> interface, which tells you when a Roi has changed, so you don't need the
> keyListener & MouseListener, and it will also detect changes of the Roi
> caused by, e.g., menu commands.
>
>    https://github.com/imagej/imagej1/blob/master/ij/gui/RoiListener.java
>
>
>
> [BTW, I did not understand your other post on CTRL-SHIFT under Fedora;
> is this about using the text tool on an image? Can you supply a
> screenshot to explain (Plugins>Utilities>Capture Delayed)? Replies in
> that thread, please]
>
> Michael
> ________________________________________________________________
> On 01.03.20 07:10, Fred Damen wrote:
>> 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
>>
>
> --
> ImageJ mailing list: http://imagej.nih.gov/ij/list.html
>

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