001/**
002 * Copyright (c) 2011, The University of Southampton and the individual contributors.
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without modification,
006 * are permitted provided that the following conditions are met:
007 *
008 *   *  Redistributions of source code must retain the above copyright notice,
009 *      this list of conditions and the following disclaimer.
010 *
011 *   *  Redistributions in binary form must reproduce the above copyright notice,
012 *      this list of conditions and the following disclaimer in the documentation
013 *      and/or other materials provided with the distribution.
014 *
015 *   *  Neither the name of the University of Southampton nor the names of its
016 *      contributors may be used to endorse or promote products derived from this
017 *      software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030/**
031 *
032 */
033package org.openimaj.vis.general;
034
035import org.openimaj.image.MBFImage;
036import org.openimaj.image.colour.ColourMap;
037import org.openimaj.image.colour.RGBColour;
038import org.openimaj.math.geometry.shape.Circle;
039import org.openimaj.vis.general.DotPlotVisualisation.ColouredDot;
040
041/**
042 *      Plots blobs proportional to the size of the value. This can be used as a
043 *      visualisation in itself or used as an {@link ItemPlotter} in other visualisations.
044 *
045 *      @author David Dupplaw (dpd@ecs.soton.ac.uk)
046 *  @created 3 Jun 2013
047 */
048public class DotPlotVisualisation extends XYPlotVisualisation<ColouredDot>
049        implements ItemPlotter<ColouredDot,Float[],MBFImage>
050{
051        /**
052         *      A dot with a specific size and colour.
053         *
054         *      @author David Dupplaw (dpd@ecs.soton.ac.uk)
055         *  @created 11 Jun 2013
056         */
057        public static class ColouredDot
058        {
059                /** The size of the dot */
060                public double size;
061
062                /** The colour of the dot */
063                public Float[] colour;
064
065                /**
066                 *      @param size
067                 *      @param colour
068                 */
069                public ColouredDot( final double size, final Float[] colour )
070                {
071                        this.size = size;
072                        this.colour = colour;
073                }
074        }
075
076        /** */
077        private static final long serialVersionUID = 1L;
078
079        /** A colour map to use */
080        private ColourMap colourMap = ColourMap.Autumn;
081
082        /** Colour map range */
083        private double colourMapMin = -1;
084
085        /** Colour map range */
086        private double colourMapMax = 1;
087
088        /**
089         *      Default construcotr
090         */
091        public DotPlotVisualisation()
092        {
093                super( null );
094                this.setItemPlotter( this );
095        }
096
097        /**
098         *      Constructor that takes the width and height of the visualisation
099         *
100         *      @param width The width of the visualisation in pixels
101         *      @param height The height of the visualisation in pixels
102         */
103        public DotPlotVisualisation( final int width, final int height )
104        {
105                super( width, height, null );
106                this.setItemPlotter( this );
107        }
108
109        /**
110         *      Adds a default coloured dot with the given size (in red).
111         *      @param x The x location
112         *      @param y The y location
113         *      @param d The size
114         */
115        public void addPoint( final double x, final double y, final double d )
116        {
117                Float[] c = RGBColour.RED;
118                if( this.colourMap != null )
119                        c = this.colourMap.apply( (float)((d-this.colourMapMin)/(this.colourMapMax-this.colourMapMin)) );
120                super.addPoint( x, y, new ColouredDot( d, c ) );
121        }
122
123        /**
124         *      {@inheritDoc}
125         *      @see org.openimaj.vis.general.ItemPlotter#plotObject(org.openimaj.image.Image, org.openimaj.vis.general.XYPlotVisualisation.LocatedObject, org.openimaj.vis.general.AxesRenderer2D)
126         */
127        @Override
128        public void plotObject( final MBFImage visImage,
129                        final XYPlotVisualisation.LocatedObject<ColouredDot> object,
130                        final AxesRenderer2D<Float[],MBFImage> renderer )
131        {
132//              System.out.println( "Object at "+object.x+","+object.y+" is plotted at "+
133//                              renderer.calculatePosition( object.x, object.y ) );
134                visImage.createRenderer().drawShapeFilled(
135                        new Circle( renderer.calculatePosition( object.x, object.y ),
136                                (float)(renderer.scaleDimensions( object.object.size, object.object.size )[0] ) ),
137                        object.object.colour );
138        }
139
140        /**
141         *      {@inheritDoc}
142         *      @see org.openimaj.vis.general.ItemPlotter#renderRestarting()
143         */
144        @Override
145        public void renderRestarting()
146        {
147        }
148
149        /**
150         *      @return the colourMap
151         */
152        public ColourMap getColourMap()
153        {
154                return this.colourMap;
155        }
156
157        /**
158         *      @param colourMap the colourMap to set
159         */
160        public void setColourMap( final ColourMap colourMap )
161        {
162                this.colourMap = colourMap;
163        }
164
165        /**
166         *      @return the colourMapRange
167         */
168        public double getColourMapMin()
169        {
170                return this.colourMapMin;
171        }
172
173        /**
174         *      @param colourMapRange the colourMapRange to set
175         */
176        public void setColourMapMin( final double colourMapRange )
177        {
178                this.colourMapMin = colourMapRange;
179        }
180
181        /**
182         *      @return the colourMapMax
183         */
184        public double getColourMapMax()
185        {
186                return this.colourMapMax;
187        }
188
189        /**
190         *      @param colourMapMax the colourMapMax to set
191         */
192        public void setColourMapMax( final double colourMapMax )
193        {
194                this.colourMapMax = colourMapMax;
195        }
196
197        /**
198         *      @param min
199         *      @param max
200         */
201        public void setColourMapRange( final double min, final double max )
202        {
203                this.colourMapMin = min;
204                this.colourMapMax = max;
205        }
206
207        /**
208         *      Main method to demonstrate the vis.
209         *      @param args command-line args (not used)
210         */
211        public static void main( final String[] args )
212        {
213                final DotPlotVisualisation dpv = new DotPlotVisualisation( 1000, 600 );
214                dpv.axesRenderer2D.setMaxXValue( 1 );
215                dpv.axesRenderer2D.setMinXValue( -1 );
216                dpv.axesRenderer2D.setMaxYValue( 1 );
217                dpv.axesRenderer2D.setMinYValue( -1 );
218                dpv.axesRenderer2D.setxMajorTickSpacing( 0.2 );
219                dpv.axesRenderer2D.setxMinorTickSpacing( 0.1 );
220                dpv.axesRenderer2D.setyMajorTickSpacing( 0.2 );
221                dpv.axesRenderer2D.setyMinorTickSpacing( 0.1 );
222                dpv.axesRenderer2D.setxAxisPosition( 300 );
223                dpv.setAutoScaleAxes( false );
224                dpv.setColourMapRange( 0, 0.2 );
225
226                for( int i = 0; i < 10; i++ )
227                        dpv.addPoint( (Math.random()-0.5)*2, (Math.random()-0.5)*2,
228                                        i/50d );
229
230                dpv.updateVis();
231                dpv.showWindow( "Dot plot" );
232        }
233}