All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.mianalysis.mia.module.visualise.plots.PlotMeasurementsScatter Maven / Gradle / Ivy

Go to download

ModularImageAnalysis (MIA) is an ImageJ plugin which provides a modular framework for assembling image and object analysis workflows. Detected objects can be transformed, filtered, measured and related. Analysis workflows are batch-enabled by default, allowing easy processing of high-content datasets.

There is a newer version: 1.6.12
Show newest version
// TODO: Add NaN exclusion for 2D plot (will have to remove items from an array (may involve intermediate ArrayLists)

package io.github.mianalysis.mia.module.visualise.plots;

import java.awt.Color;

import org.scijava.Priority;
import org.scijava.plugin.Plugin;

import ij.gui.Plot;
import io.github.mianalysis.mia.module.Categories;
import io.github.mianalysis.mia.module.Category;
import io.github.mianalysis.mia.module.Module;
import io.github.mianalysis.mia.module.Modules;
import io.github.mianalysis.mia.object.Obj;
import io.github.mianalysis.mia.object.Objs;
import io.github.mianalysis.mia.object.Workspace;
import io.github.mianalysis.mia.object.image.Image;
import io.github.mianalysis.mia.object.image.ImageFactory;
import io.github.mianalysis.mia.object.parameters.BooleanP;
import io.github.mianalysis.mia.object.parameters.ChoiceP;
import io.github.mianalysis.mia.object.parameters.InputObjectsP;
import io.github.mianalysis.mia.object.parameters.ObjectMeasurementP;
import io.github.mianalysis.mia.object.parameters.OutputImageP;
import io.github.mianalysis.mia.object.parameters.Parameters;
import io.github.mianalysis.mia.object.parameters.SeparatorP;
import io.github.mianalysis.mia.object.refs.collections.ImageMeasurementRefs;
import io.github.mianalysis.mia.object.refs.collections.MetadataRefs;
import io.github.mianalysis.mia.object.refs.collections.ObjMeasurementRefs;
import io.github.mianalysis.mia.object.refs.collections.ObjMetadataRefs;
import io.github.mianalysis.mia.object.refs.collections.ParentChildRefs;
import io.github.mianalysis.mia.object.refs.collections.PartnerRefs;
import io.github.mianalysis.mia.object.system.Status;
import io.github.mianalysis.mia.process.math.CumStat;

/**
 * Created by sc13967 on 19/05/2017.
 */

/**
* Creates an ImageJ scatter plot of two measurements associated with specified objects.  A third measurement can be encoded as point colour.  The output plot can either be displayed immediately in an interactive ImageJ plotting window or stored as an image to the MIA workspace (allowing it to subsequently be saved to file).
*/
@Plugin(type = Module.class, priority=Priority.LOW, visible=true)
public class PlotMeasurementsScatter extends Module {

	/**
	* 
	*/
    public static final String INPUT_SEPARATOR = "Object input/image output";

	/**
	* Input object collection for which object-associated measurements will be plotted.
	*/
    public static final String INPUT_OBJECTS = "Input objects";

	/**
	* Output plot image which will be saved to the workspace with this name.
	*/
    public static final String OUTPUT_IMAGE = "Output image";


	/**
	* 
	*/
    public static final String PLOTTING_SEPARATOR = "Plotting controls";
    public static final String MEASUREMENT1 = "First measurement (X)";
    public static final String MEASUREMENT2 = "Second measurement (Y)";

	/**
	* When selected, a third measurement can be represented as the plot marker colour.  This colour will vary according to the colourmap set with the "Colourmap" parameter
	*/
    public static final String INCLUDE_COLOUR = "Add third measurement as colour";
    public static final String MEASUREMENT3 = "Third measurement (Colour)";

	/**
	* If "Add third measurement as colour" is selected, this is the colourmap that will control how marker colours vary in response to the magnitude of their values.
	*/
    public static final String COLOURMAP = "Colourmap";


	/**
	* 
	*/
    public static final String MISC_SEPARATOR = "Miscellaneous controls";

	/**
	* When selected, and if displaying module output in realtime ("Show output" button selected), the plot will be displayed as an interactive ImageJ plot (editable rendering).  Otherwise, the standard image output will be displayed (i.e. the same image added to the workspace).
	*/
    public static final String SHOW_AS_INTERACTIVE_PLOT = "Show as interactive plot";

    public PlotMeasurementsScatter(Modules modules) {
        super("Plot measurements as scatter", modules);
    }

    public interface ColourMaps {
        String RED_TO_BLUE = "Red to blue";
        String RED_TO_GREEN = "Blue to green";

        String[] ALL = new String[] { "Red to blue", "Red to green" };

    }

    private Color[] createColourGradient(double startH, double endH, double[] values) {
        // Getting colour range
        CumStat cs = new CumStat();
        for (double value : values)
            cs.addMeasure(value);
        double min = cs.getMin();
        double max = cs.getMax();

        Color[] colours = new Color[values.length];
        for (int i = 0; i < colours.length; i++) {
            double H = (values[i] - min) * (endH - startH) / (max - min) + startH;
            colours[i] = Color.getHSBColor((float) H, 1, 1);

        }

        return colours;

    }

    @Override
    public Category getCategory() {
        return Categories.VISUALISATION_PLOTS;
    }

    @Override
    public String getVersionNumber() {
        return "1.0.0";
    }

    @Override
    public String getDescription() {
        return "Creates an ImageJ scatter plot of two measurements associated with specified objects.  A third measurement can be encoded as point colour.  The output plot can either be displayed immediately in an interactive ImageJ plotting window or stored as an image to the MIA workspace (allowing it to subsequently be saved to file).";
    }

    @Override
    public Status process(Workspace workspace) {
        // Getting input objects
        String inputObjectsName = parameters.getValue(INPUT_OBJECTS,workspace);
        Objs inputObjects = workspace.getObjects().get(inputObjectsName);

        // Getting parameters
        String outputImageName = parameters.getValue(OUTPUT_IMAGE,workspace);
        boolean useColour = parameters.getValue(INCLUDE_COLOUR,workspace);
        String measurement1 = parameters.getValue(MEASUREMENT1,workspace);
        String measurement2 = parameters.getValue(MEASUREMENT2,workspace);
        String measurement3 = parameters.getValue(MEASUREMENT3,workspace);
        String colourmap = parameters.getValue(COLOURMAP,workspace);
        boolean showInteractive = parameters.getValue(SHOW_AS_INTERACTIVE_PLOT,workspace);

        // Getting measurement values
        double[] measurementValues1 = new double[inputObjects.size()];
        double[] measurementValues2 = new double[inputObjects.size()];
        double[] measurementValues3 = null;
        if (useColour)
            measurementValues3 = new double[inputObjects.size()];

        CumStat[] cs = new CumStat[2];
        cs[0] = new CumStat();
        cs[1] = new CumStat();

        int iter = 0;
        for (Obj inputObject : inputObjects.values()) {
            measurementValues1[iter] = inputObject.getMeasurement(measurement1).getValue();
            measurementValues2[iter] = inputObject.getMeasurement(measurement2).getValue();
            if (useColour)
                measurementValues3[iter] = inputObject.getMeasurement(measurement3).getValue();

            // Adding the current measurements to MultiCumStat, so the min and max can be
            // obtained
            cs[0].addMeasure(measurementValues1[iter]);
            cs[1].addMeasure(measurementValues2[iter++]);

        }

        // Creating the scatter plot
        Plot plot;
        if (useColour) {
            String title = "Scatter plot of " + measurement1 + ", " + measurement2 + " and " + measurement3;
            plot = new Plot(title, measurement1, measurement2);

            Color[] colors = null;
            if (colourmap.equals(ColourMaps.RED_TO_BLUE)) // Red to blue
                colors = createColourGradient(0, 240d / 255d, measurementValues3);
            else if (colourmap.equals(ColourMaps.RED_TO_GREEN)) // Red to green
                colors = createColourGradient(0, 120d / 255d, measurementValues3);

            for (int i = 0; i < measurementValues1.length; i++) {
                // Adding the current point (with its assigned colour)
                plot.setColor(colors[i], colors[i]);

                if (measurementValues1[i] != Double.NaN & measurementValues2[i] != Double.NaN
                        & measurementValues3[i] != Double.NaN)
                    plot.addPoints(new double[] { measurementValues1[i] }, new double[] { measurementValues2[i] },
                            Plot.CIRCLE);

            }
        } else {
            String title = "Scatter plot of " + measurement1 + " and " + measurement2;
            plot = new Plot(title, measurement1, measurement2);
            plot.addPoints(measurementValues1, measurementValues2, 0);
        }

        plot.setLimits(cs[0].getMin(), cs[0].getMax(), cs[1].getMin(), cs[1].getMax());

        Image outputImage = ImageFactory.createImage(outputImageName, plot.getImagePlus());
        workspace.addImage(outputImage);

        if (showOutput)
            if (showInteractive)
                plot.show();
            else
                outputImage.show();

        return Status.PASS;

    }

    @Override
    protected void initialiseParameters() {
        parameters.add(new SeparatorP(INPUT_SEPARATOR, this));
        parameters.add(new InputObjectsP(INPUT_OBJECTS, this));
        parameters.add(new OutputImageP(OUTPUT_IMAGE, this));

        parameters.add(new SeparatorP(PLOTTING_SEPARATOR, this));
        parameters.add(new ObjectMeasurementP(MEASUREMENT1, this));
        parameters.add(new ObjectMeasurementP(MEASUREMENT2, this));
        parameters.add(new BooleanP(INCLUDE_COLOUR, this, false));
        parameters.add(new ObjectMeasurementP(MEASUREMENT3, this));
        parameters.add(new ChoiceP(COLOURMAP, this, ColourMaps.RED_TO_BLUE, ColourMaps.ALL));

        parameters.add(new SeparatorP(MISC_SEPARATOR, this));
        parameters.add(new BooleanP(SHOW_AS_INTERACTIVE_PLOT, this, true));

        addParameterDescriptions();

    }

    @Override
    public Parameters updateAndGetParameters() {
Workspace workspace = null;
        Parameters returnedParameters = new Parameters();

        returnedParameters.add(parameters.getParameter(INPUT_SEPARATOR));
        returnedParameters.add(parameters.getParameter(INPUT_OBJECTS));
        returnedParameters.add(parameters.getParameter(OUTPUT_IMAGE));

        returnedParameters.add(parameters.getParameter(PLOTTING_SEPARATOR));
        returnedParameters.add(parameters.getParameter(MEASUREMENT1));
        returnedParameters.add(parameters.getParameter(MEASUREMENT2));

        // Updating measurements with measurement choices from currently-selected object
        String objectName = parameters.getValue(INPUT_OBJECTS,workspace);
        ((ObjectMeasurementP) parameters.getParameter(MEASUREMENT1)).setObjectName(objectName);
        ((ObjectMeasurementP) parameters.getParameter(MEASUREMENT2)).setObjectName(objectName);

        returnedParameters.add(parameters.getParameter(INCLUDE_COLOUR));
        if ((boolean) parameters.getValue(INCLUDE_COLOUR,workspace)) {
            returnedParameters.add(parameters.getParameter(MEASUREMENT3));
            returnedParameters.add(parameters.getParameter(COLOURMAP));
            ((ObjectMeasurementP) parameters.getParameter(MEASUREMENT3)).setObjectName(objectName);
        }

        returnedParameters.add(parameters.getParameter(MISC_SEPARATOR));
        returnedParameters.add(parameters.getParameter(SHOW_AS_INTERACTIVE_PLOT));

        return returnedParameters;

    }

    @Override
    public ImageMeasurementRefs updateAndGetImageMeasurementRefs() {
return null;
    }

    @Override
public ObjMeasurementRefs updateAndGetObjectMeasurementRefs() {
return null;
    }

    @Override
    public ObjMetadataRefs updateAndGetObjectMetadataRefs() {  
	return null; 
    }

    @Override
    public MetadataRefs updateAndGetMetadataReferences() {
return null;
    }

    @Override
    public ParentChildRefs updateAndGetParentChildRefs() {
return null;
    }

    @Override
    public PartnerRefs updateAndGetPartnerRefs() {
return null;
    }

    @Override
    public boolean verify() {
        return true;
    }

    void addParameterDescriptions() {
        parameters.get(INPUT_OBJECTS)
                .setDescription("Input object collection for which object-associated measurements will be plotted.");

        parameters.get(OUTPUT_IMAGE)
                .setDescription("Output plot image which will be saved to the workspace with this name.");

        parameters.get(MEASUREMENT1).setDescription(
                "Measurement associated with the input objects which will be plotted along the x-axis.");

        parameters.get(MEASUREMENT2).setDescription(
                "Measurement associated with the input objects which will be plotted along the y-axis.");

        parameters.get(INCLUDE_COLOUR).setDescription(
                "When selected, a third measurement can be represented as the plot marker colour.  This colour will vary according to the colourmap set with the \""
                        + COLOURMAP + "\" parameter");

        parameters.get(MEASUREMENT3).setDescription("If \"" + INCLUDE_COLOUR
                + "\" is selected, this measurement associated with the input objects will determine the plot marker colour.");

        parameters.get(COLOURMAP).setDescription("If \"" + INCLUDE_COLOUR
                + "\" is selected, this is the colourmap that will control how marker colours vary in response to the magnitude of their values.");

        parameters.get(SHOW_AS_INTERACTIVE_PLOT).setDescription(
                "When selected, and if displaying module output in realtime (\"Show output\" button selected), the plot will be displayed as an interactive ImageJ plot (editable rendering).  Otherwise, the standard image output will be displayed (i.e. the same image added to the workspace).");

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy