/*- * #%L * Fiji distribution of ImageJ for the life sciences. * %% * Copyright (C) 2007 - 2017 Fiji developers. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-2.0.html>. * #L% */ package spim.fiji.plugin.thinout; import ij.ImageJ; import java.awt.Color; import java.awt.Dimension; import java.awt.event.WindowEvent; import java.util.ArrayList; import java.util.List; import java.util.Random; import net.imglib2.util.ValuePair; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.StandardXYBarPainter; import org.jfree.chart.renderer.xy.XYBarRenderer; import org.jfree.data.xy.IntervalXYDataset; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import org.jfree.ui.ApplicationFrame; import org.jfree.ui.RefineryUtilities; public class Histogram extends ApplicationFrame { private static final long serialVersionUID = 1L; protected double min, max; public Histogram( final List< Double > values, final int numBins, final String title, final String units ) { super( title ); final IntervalXYDataset dataset = createDataset( values, numBins, title ); final JFreeChart chart = createChart( dataset, title, units ); final ChartPanel chartPanel = new ChartPanel( chart ); chartPanel.addChartMouseListener( new MouseListenerValue( chartPanel, getMin() + ( getMax() - getMin() ) / 2 )); chartPanel.setPreferredSize( new Dimension( 600, 270 ) ); setContentPane( chartPanel ); } public void showHistogram() { this.pack(); RefineryUtilities.centerFrameOnScreen( this ); this.setVisible( true ); } public double getMin() { return min; } public double getMax() { return max; } public static ValuePair< Double, Double > getMinMax( final List< Double > data ) { // compute min/max/size double min = data.get( 0 ); double max = data.get( 0 ); for ( final double v : data ) { min = Math.min( min, v ); max = Math.max( max, v ); } return new ValuePair< Double, Double >( min, max ); } public static List< ValuePair< Double, Integer > > binData( final List< Double > data, final double min, final double max, final int numBins ) { // avoid the one value that is exactly 100% final double size = max - min + 0.000001; // bin and count the entries final int[] bins = new int[ numBins ]; for ( final double v : data ) ++bins[ (int)Math.floor( ( ( v - min ) / size ) * numBins ) ]; // make the list of bins final ArrayList< ValuePair< Double, Integer > > hist = new ArrayList< ValuePair< Double, Integer > >(); final double binSize = size / numBins; for ( int bin = 0; bin < numBins; ++bin ) hist.add( new ValuePair< Double, Integer >( min + binSize/2 + binSize * bin, bins[ bin ] ) ); return hist; } protected IntervalXYDataset createDataset( final List< Double > values, final int numBins, final String title ) { final XYSeries series = new XYSeries( title ); final ValuePair< Double, Double > minmax = getMinMax( values ); this.min = minmax.getA(); this.max = minmax.getB(); final List< ValuePair< Double, Integer > > hist = binData( values, min, max, numBins ); for ( final ValuePair< Double, Integer > pair : hist ) series.add( pair.getA(), pair.getB() ); final XYSeriesCollection dataset = new XYSeriesCollection( series ); dataset.setAutoWidth( true ); return dataset; } protected JFreeChart createChart( final IntervalXYDataset dataset, final String title, final String units ) { final JFreeChart chart = ChartFactory.createXYBarChart( title, "Distance [" + units + "]", false, "Count", dataset, PlotOrientation.VERTICAL, false, // legend false, false ); NumberAxis range = (NumberAxis) chart.getXYPlot().getDomainAxis(); range.setRange( getMin(), getMax() ); XYPlot plot = chart.getXYPlot(); XYBarRenderer renderer = (XYBarRenderer) plot.getRenderer(); renderer.setSeriesPaint( 0, Color.red ); renderer.setDrawBarOutline( true ); renderer.setSeriesOutlinePaint( 0, Color.black ); renderer.setBarPainter( new StandardXYBarPainter() ); return chart; } @Override public void windowClosing( final WindowEvent evt ) { if( evt.getWindow() == this ) dispose(); } public static void main( final String[] args ) { new ImageJ(); final List< Double > values = new ArrayList< Double >(); final Random rnd = new Random(); for ( int i = 0; i < 10000; ++i ) values.add( rnd.nextGaussian() ); final Histogram demo = new Histogram( values, 100, "Histogram for ...", "pixels" ); demo.pack(); RefineryUtilities.centerFrameOnScreen(demo); demo.setVisible( true ); } }