/* * Apache License * Version 2.0, January 2004 * http://www.apache.org/licenses/ * * Copyright 2013 Aurelian Tutuianu * Copyright 2014 Aurelian Tutuianu * Copyright 2015 Aurelian Tutuianu * Copyright 2016 Aurelian Tutuianu * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package rapaio.graphics.plot.plotcomp; import rapaio.data.Var; import rapaio.graphics.base.Range; import rapaio.graphics.opt.GOpt; import rapaio.graphics.plot.Plot; import rapaio.graphics.plot.PlotComponent; import java.awt.*; import java.awt.geom.Rectangle2D; /** * Created by <a href="mailto:padreati@yahoo.com">Aurelian Tutuianu</a> at 12/5/14. */ public class Histogram2D extends PlotComponent { private static final long serialVersionUID = 136436073834179971L; private final Var x; private final Var y; private int[][] freq; private int maxFreq; public Histogram2D(Var x, Var y, GOpt... opts) { this.x = x; this.y = y; this.options.apply(opts); } @Override public void initialize(Plot parent) { super.initialize(parent); parent.leftMarkers(true); parent.leftThick(true); parent.xLab(x.name()); parent.bottomMarkers(true); parent.bottomThick(true); parent.yLab(y.name()); this.options.setBinsDefault(gOpts -> 10); } @Override protected Range buildRange() { if (x.rowCount() == 0) { return null; } Range range = new Range(); for (int i = 0; i < Math.min(x.rowCount(), y.rowCount()); i++) { if (x.missing(i) || y.missing(i)) { continue; } range.union(x.value(i), y.value(i)); } return range; } private void computeData() { Range range = buildRange(); int bins = options.getBins(); double w = range.width() / bins; double h = range.height() / bins; freq = new int[bins][bins]; for (int i = 0; i < Math.min(x.rowCount(), y.rowCount()); i++) { if (x.missing(i) || y.missing(i)) continue; int xx = Math.min(bins - 1, (int) Math.floor((x.value(i) - range.x1()) / w)); int yy = Math.min(bins - 1, (int) Math.floor((y.value(i) - range.y1()) / h)); freq[xx][yy]++; if (maxFreq < freq[xx][yy]) { maxFreq = freq[xx][yy]; } } } @Override public void paint(Graphics2D g2d) { computeData(); // paint each rectangle as a blue gradient int bins = options.getBins(); Range range = buildRange(); double w = range.width() / bins; double h = range.height() / bins; for (int i = 0; i < bins; i++) { for (int j = 0; j < bins; j++) { int blue = (int) (255 * freq[i][j] / (1.0 * maxFreq)); Color c = options.getColor(0); Color color = new Color(c.getRed(), c.getGreen(), c.getBlue(), blue); g2d.setColor(color); Rectangle2D.Double rr = new Rectangle2D.Double( parent.xScale(range.x1() + w * i), parent.yScale(range.y1() + h * j + h), parent.xScale(range.x1() + w * i + w) - parent.xScale(range.x1() + w * i), parent.yScale(range.y1() + h * j) - parent.yScale(range.y1() + h * j + h)); g2d.fill(rr); } } } }