diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/visualization/projector')
9 files changed, 820 insertions, 0 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramFactory.java new file mode 100644 index 00000000..06e94891 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramFactory.java @@ -0,0 +1,103 @@ +package de.lmu.ifi.dbs.elki.visualization.projector; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2011 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.data.type.TypeUtil; +import de.lmu.ifi.dbs.elki.database.Database; +import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.result.HierarchicalResult; +import de.lmu.ifi.dbs.elki.result.Result; +import de.lmu.ifi.dbs.elki.result.ResultUtil; +import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterEqualConstraint; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter; + +/** + * Produce one-dimensional projections. + * + * @author Erich Schubert + */ +// TODO: re-add maxdim option +public class HistogramFactory implements ProjectorFactory { + /** + * Maximum dimensionality + */ + private int maxdim = ScatterPlotFactory.MAX_DIMENSIONS_DEFAULT; + + /** + * Constructor. + * @param maxdim Maximum dimensionality + */ + public HistogramFactory(int maxdim) { + super(); + this.maxdim = maxdim; + } + + @Override + public void processNewResult(HierarchicalResult baseResult, Result newResult) { + Database db = ResultUtil.findDatabase(newResult); + if(db != null) { + for(Relation<?> rel : db.getRelations()) { + if(TypeUtil.NUMBER_VECTOR_FIELD.isAssignableFromType(rel.getDataTypeInformation())) { + @SuppressWarnings("unchecked") + Relation<NumberVector<?, ?>> vrel = (Relation<NumberVector<?, ?>>) rel; + final int dim = DatabaseUtil.dimensionality(vrel); + HistogramProjector<NumberVector<?, ?>> proj = new HistogramProjector<NumberVector<?, ?>>(vrel, Math.min(dim, maxdim)); + baseResult.getHierarchy().add(vrel, proj); + } + } + } + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + /** + * Stores the maximum number of dimensions to show. + */ + private int maxdim = ScatterPlotFactory.MAX_DIMENSIONS_DEFAULT; + + @Override + protected void makeOptions(Parameterization config) { + super.makeOptions(config); + IntParameter maxdimP = new IntParameter(ScatterPlotFactory.Parameterizer.MAXDIM_ID, new GreaterEqualConstraint(1), ScatterPlotFactory.MAX_DIMENSIONS_DEFAULT); + if(config.grab(maxdimP)) { + maxdim = maxdimP.getValue(); + } + } + + @Override + protected HistogramFactory makeInstance() { + return new HistogramFactory(maxdim); + } + } +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java new file mode 100644 index 00000000..5ddc7b32 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/HistogramProjector.java @@ -0,0 +1,125 @@ +package de.lmu.ifi.dbs.elki.visualization.projector; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2011 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.result.AbstractHierarchicalResult; +import de.lmu.ifi.dbs.elki.result.ResultUtil; +import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil; +import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; +import de.lmu.ifi.dbs.elki.visualization.gui.overview.PlotItem; +import de.lmu.ifi.dbs.elki.visualization.projections.Projection1D; +import de.lmu.ifi.dbs.elki.visualization.projections.Simple1D; +import de.lmu.ifi.dbs.elki.visualization.scales.LinearScale; +import de.lmu.ifi.dbs.elki.visualization.scales.Scales; +import de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj.LabelVisFactory; + +/** + * ScatterPlotProjector is responsible for producing a set of scatterplot + * visualizations. + * + * @author Erich Schubert + * + * @param <V> Vector type + */ +public class HistogramProjector<V extends NumberVector<?, ?>> extends AbstractHierarchicalResult implements Projector { + /** + * Relation we project + */ + Relation<V> rel; + + /** + * Database dimensionality + */ + int dmax; + + /** + * Axis scales + */ + LinearScale[] scales; + + /** + * Constructor. + * + * @param rel Relation + * @param maxdim Maximum dimension to use + */ + public HistogramProjector(Relation<V> rel, int maxdim) { + super(); + this.rel = rel; + this.dmax = maxdim; + this.scales = Scales.calcScales(rel); + assert (maxdim <= DatabaseUtil.dimensionality(rel)) : "Requested dimensionality larger than data dimensionality?!?"; + } + + @Override + public Collection<PlotItem> arrange() { + List<PlotItem> layout = new ArrayList<PlotItem>(1); + List<VisualizationTask> tasks = ResultUtil.filterResults(this, VisualizationTask.class); + if (tasks.size() > 0){ + PlotItem master = new PlotItem(dmax + .1, .5 + .1, null); + for(int d1 = 1; d1 <= dmax; d1++) { + Projection1D proj = new Simple1D(scales, d1); + final PlotItem it = new PlotItem(d1 - 1 + .1, 0. + .1, 1., .5, proj); + it.visualizations = tasks; + master.subitems.add(it); + } + layout.add(master); + for(int d1 = 1; d1 <= dmax; d1++) { + PlotItem it = new PlotItem(d1 - 1 + .1, 0, 1., .1, null); + final VisualizationTask task = new VisualizationTask("", null, null, new LabelVisFactory(DatabaseUtil.getColumnLabel(rel, d1))); + task.height = .1; + task.width = 1; + task.put(VisualizationTask.META_NODETAIL, true); + it.visualizations.add(task); + master.subitems.add(it); + } + } + return layout; + } + + @Override + public String getLongName() { + return "Axis plot"; + } + + @Override + public String getShortName() { + return "axisplot"; + } + + /** + * Get the relation we project. + * + * @return Relation + */ + public Relation<V> getRelation() { + return rel; + } +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjector.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjector.java new file mode 100644 index 00000000..21b9c227 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjector.java @@ -0,0 +1,108 @@ +package de.lmu.ifi.dbs.elki.visualization.projector; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2011 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import de.lmu.ifi.dbs.elki.distance.distancevalue.Distance; +import de.lmu.ifi.dbs.elki.result.AbstractHierarchicalResult; +import de.lmu.ifi.dbs.elki.result.ResultUtil; +import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult; +import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; +import de.lmu.ifi.dbs.elki.visualization.VisualizerContext; +import de.lmu.ifi.dbs.elki.visualization.gui.overview.PlotItem; +import de.lmu.ifi.dbs.elki.visualization.opticsplot.OPTICSPlot; + +/** + * Projection for OPTICS plots. + * + * @author Erich Schubert + */ +public class OPTICSProjector<D extends Distance<D>> extends AbstractHierarchicalResult implements Projector { + /** + * Cluster order result + */ + private ClusterOrderResult<D> clusterOrder; + + /** + * OPTICS plot image + */ + private OPTICSPlot<D> plot = null; + + /** + * Constructor. + * + * @param co Cluster order + */ + public OPTICSProjector(ClusterOrderResult<D> co) { + super(); + this.clusterOrder = co; + } + + @Override + public String getLongName() { + return "OPTICS projection"; + } + + @Override + public String getShortName() { + return "optics"; + } + + @Override + public Collection<PlotItem> arrange() { + List<PlotItem> col = new ArrayList<PlotItem>(1); + List<VisualizationTask> tasks = ResultUtil.filterResults(this, VisualizationTask.class); + if (tasks.size() > 0) { + final PlotItem it = new PlotItem(4., 1., null); + it.visualizations = tasks; + col.add(it); + } + return col; + } + + /** + * Get the cluster order + * + * @return the cluster order + */ + public ClusterOrderResult<D> getResult() { + return clusterOrder; + } + + /** + * Get or produce the actual OPTICS plot. + * + * @param context Context to use + * @return Plot + */ + public OPTICSPlot<D> getOPTICSPlot(VisualizerContext context) { + if(plot == null) { + plot = OPTICSPlot.plotForClusterOrder(clusterOrder, context); + } + return plot; + } +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjectorFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjectorFactory.java new file mode 100644 index 00000000..580eb532 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/OPTICSProjectorFactory.java @@ -0,0 +1,59 @@ +package de.lmu.ifi.dbs.elki.visualization.projector; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2011 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import java.util.Collection; + +import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance; +import de.lmu.ifi.dbs.elki.result.HierarchicalResult; +import de.lmu.ifi.dbs.elki.result.Result; +import de.lmu.ifi.dbs.elki.result.ResultUtil; +import de.lmu.ifi.dbs.elki.result.optics.ClusterOrderResult; +import de.lmu.ifi.dbs.elki.visualization.opticsplot.OPTICSPlot; + +/** + * Produce OPTICS plot projections + * + * @author Erich Schubert + */ +public class OPTICSProjectorFactory implements ProjectorFactory { + /** + * Constructor. + */ + public OPTICSProjectorFactory() { + super(); + } + + @Override + public void processNewResult(HierarchicalResult baseResult, Result newResult) { + Collection<ClusterOrderResult<?>> cos = ResultUtil.filterResults(newResult, ClusterOrderResult.class); + for(ClusterOrderResult<?> co : cos) { + if(OPTICSPlot.canPlot(co)) { + @SuppressWarnings("unchecked") + OPTICSProjector<?> proj = new OPTICSProjector<DoubleDistance>((ClusterOrderResult<DoubleDistance>) co); + baseResult.getHierarchy().add(co, proj); + } + } + } +} diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/Projector.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/Projector.java new file mode 100644 index 00000000..646adda5 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/Projector.java @@ -0,0 +1,43 @@ +package de.lmu.ifi.dbs.elki.visualization.projector; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2011 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import java.util.Collection; + +import de.lmu.ifi.dbs.elki.result.HierarchicalResult; +import de.lmu.ifi.dbs.elki.visualization.gui.overview.PlotItem; + +/** + * A projector is responsible for adding projections to the visualization. + * + * @author Erich Schubert + */ +public interface Projector extends HierarchicalResult { + /** + * Produce an arrangement of projections. + * + * @return Arrangement. + */ + public Collection<PlotItem> arrange(); +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/ProjectorFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/ProjectorFactory.java new file mode 100644 index 00000000..d0996822 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/ProjectorFactory.java @@ -0,0 +1,46 @@ +package de.lmu.ifi.dbs.elki.visualization.projector; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2011 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import de.lmu.ifi.dbs.elki.result.HierarchicalResult; +import de.lmu.ifi.dbs.elki.result.Result; +import de.lmu.ifi.dbs.elki.result.ResultProcessor; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.Parameterizable; + +/** + * A projector is responsible for adding projections to the visualization by + * detecting appropriate relations in the database. + * + * @author Erich Schubert + */ +public interface ProjectorFactory extends ResultProcessor, Parameterizable { + /** + * Add projections for the given result (tree) to the result tree. + * + * @param baseResult Context to work with + * @param newResult Result to process + */ + @Override + public void processNewResult(HierarchicalResult baseResult, Result newResult); +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotFactory.java new file mode 100644 index 00000000..3d996bdc --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotFactory.java @@ -0,0 +1,121 @@ +package de.lmu.ifi.dbs.elki.visualization.projector; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2011 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.data.type.TypeUtil; +import de.lmu.ifi.dbs.elki.database.Database; +import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.result.HierarchicalResult; +import de.lmu.ifi.dbs.elki.result.Result; +import de.lmu.ifi.dbs.elki.result.ResultUtil; +import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.constraints.GreaterEqualConstraint; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization; +import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.IntParameter; + +/** + * Produce scatterplot projections. + * + * @author Erich Schubert + */ +// TODO: re-add maxdim option +public class ScatterPlotFactory implements ProjectorFactory { + /** + * Maximum number of dimensions to visualize. + * + * TODO: Erich: add scrolling function for higher dimensionality! + */ + public static final int MAX_DIMENSIONS_DEFAULT = 10; + + /** + * Stores the maximum number of dimensions to show. + */ + private int maxdim = MAX_DIMENSIONS_DEFAULT; + + /** + * Constructor. + * + * @param maxdim Maximum number of dimensions to show. + */ + public ScatterPlotFactory(int maxdim) { + super(); + this.maxdim = maxdim; + } + + @Override + public void processNewResult(HierarchicalResult baseResult, Result newResult) { + Database db = ResultUtil.findDatabase(newResult); + if(db != null) { + for(Relation<?> rel : db.getRelations()) { + if(TypeUtil.NUMBER_VECTOR_FIELD.isAssignableFromType(rel.getDataTypeInformation())) { + @SuppressWarnings("unchecked") + Relation<NumberVector<?, ?>> vrel = (Relation<NumberVector<?, ?>>) rel; + final int dim = DatabaseUtil.dimensionality(vrel); + ScatterPlotProjector<NumberVector<?, ?>> proj = new ScatterPlotProjector<NumberVector<?, ?>>(vrel, Math.min(maxdim, dim)); + baseResult.getHierarchy().add(vrel, proj); + } + } + } + } + + /** + * Parameterization class. + * + * @author Erich Schubert + * + * @apiviz.exclude + */ + public static class Parameterizer extends AbstractParameterizer { + /** + * Parameter for the maximum number of dimensions, + * + * <p> + * Code: -vis.maxdim + * </p> + */ + public static final OptionID MAXDIM_ID = OptionID.getOrCreateOptionID("vis.maxdim", "Maximum number of dimensions to display."); + + /** + * Stores the maximum number of dimensions to show. + */ + private int maxdim = MAX_DIMENSIONS_DEFAULT; + + @Override + protected void makeOptions(Parameterization config) { + super.makeOptions(config); + IntParameter maxdimP = new IntParameter(MAXDIM_ID, new GreaterEqualConstraint(1), MAX_DIMENSIONS_DEFAULT); + if(config.grab(maxdimP)) { + maxdim = maxdimP.getValue(); + } + } + + @Override + protected Object makeInstance() { + return new ScatterPlotFactory(maxdim); + } + } +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java new file mode 100644 index 00000000..ee692531 --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/ScatterPlotProjector.java @@ -0,0 +1,189 @@ +package de.lmu.ifi.dbs.elki.visualization.projector; + +/* + This file is part of ELKI: + Environment for Developing KDD-Applications Supported by Index-Structures + + Copyright (C) 2011 + Ludwig-Maximilians-Universität München + Lehr- und Forschungseinheit für Datenbanksysteme + ELKI Development Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 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 Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import de.lmu.ifi.dbs.elki.data.NumberVector; +import de.lmu.ifi.dbs.elki.database.relation.Relation; +import de.lmu.ifi.dbs.elki.math.linearalgebra.AffineTransformation; +import de.lmu.ifi.dbs.elki.result.AbstractHierarchicalResult; +import de.lmu.ifi.dbs.elki.result.ResultUtil; +import de.lmu.ifi.dbs.elki.utilities.DatabaseUtil; +import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; +import de.lmu.ifi.dbs.elki.visualization.gui.overview.PlotItem; +import de.lmu.ifi.dbs.elki.visualization.projections.AffineProjection; +import de.lmu.ifi.dbs.elki.visualization.projections.Projection2D; +import de.lmu.ifi.dbs.elki.visualization.projections.Simple2D; +import de.lmu.ifi.dbs.elki.visualization.scales.LinearScale; +import de.lmu.ifi.dbs.elki.visualization.scales.Scales; +import de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj.LabelVisFactory; + +/** + * ScatterPlotProjector is responsible for producing a set of scatterplot + * visualizations. + * + * @author Erich Schubert + * + * @param <V> Vector type + */ +// FIXME: re-add column labels +public class ScatterPlotProjector<V extends NumberVector<?, ?>> extends AbstractHierarchicalResult implements Projector { + /** + * Relation we project + */ + Relation<V> rel; + + /** + * Database dimensionality + */ + int dmax; + + /** + * Axis scales + */ + LinearScale[] scales; + + /** + * Constructor. + * + * @param rel Relation + * @param maxdim Maximum dimension to use + */ + public ScatterPlotProjector(Relation<V> rel, int maxdim) { + super(); + this.rel = rel; + this.dmax = maxdim; + this.scales = Scales.calcScales(rel); + assert (maxdim <= DatabaseUtil.dimensionality(rel)) : "Requested dimensionality larger than data dimensionality?!?"; + } + + @Override + public Collection<PlotItem> arrange() { + List<PlotItem> layout = new ArrayList<PlotItem>(1); + List<VisualizationTask> tasks = ResultUtil.filterResults(this, VisualizationTask.class); + if(tasks.size() > 0) { + final PlotItem master; + if(dmax == 2) { + // In 2d, make the plot twice as big. + master = new PlotItem(2 + .1, 2 + .1, null); + { + Projection2D proj = new Simple2D(scales, 1, 2); + PlotItem it = new PlotItem(.1, 0, 2., 2., proj); + it.visualizations = tasks; + master.subitems.add(it); + } + // Label at bottom + { + PlotItem it = new PlotItem(.1, 2., 2., .1, null); + final VisualizationTask task = new VisualizationTask("", null, null, new LabelVisFactory(DatabaseUtil.getColumnLabel(rel, 1))); + task.height = .1; + task.width = 2.; + task.put(VisualizationTask.META_NODETAIL, true); + it.visualizations.add(task); + master.subitems.add(it); + } + // Label on left + { + PlotItem it = new PlotItem(0, 0, .1, 2, null); + final VisualizationTask task = new VisualizationTask("", null, null, new LabelVisFactory(DatabaseUtil.getColumnLabel(rel, 2), true)); + task.height = 2.; + task.width = .1; + task.put(VisualizationTask.META_NODETAIL, true); + it.visualizations.add(task); + master.subitems.add(it); + } + } + else { + final double sizeh = Math.ceil((dmax - 1) / 2.0); + master = new PlotItem(sizeh * 2 + .1, dmax - 1 + .1, null); + + for(int d1 = 1; d1 < dmax; d1++) { + for(int d2 = d1 + 1; d2 <= dmax; d2++) { + Projection2D proj = new Simple2D(scales, d1, d2); + PlotItem it = new PlotItem(d1 - 1 + .1, d2 - 2, 1., 1., proj); + it.visualizations = tasks; + master.subitems.add(it); + } + } + if(dmax >= 3) { + AffineTransformation p = AffineProjection.axisProjection(DatabaseUtil.dimensionality(rel), 1, 2); + p.addRotation(0, 2, Math.PI / 180 * -10.); + p.addRotation(1, 2, Math.PI / 180 * 15.); + // Wanna try 4d? go ahead: + // p.addRotation(0, 3, Math.PI / 180 * -20.); + // p.addRotation(1, 3, Math.PI / 180 * 30.); + Projection2D proj = new AffineProjection(scales, p); + PlotItem it = new PlotItem(sizeh + .1, 0, sizeh, sizeh, proj); + it.visualizations = tasks; + master.subitems.add(it); + } + // Labels at bottom + for(int d1 = 1; d1 < dmax; d1++) { + PlotItem it = new PlotItem(d1 - 1 + .1, dmax - 1, 1., .1, null); + final VisualizationTask task = new VisualizationTask("", null, null, new LabelVisFactory(DatabaseUtil.getColumnLabel(rel, d1))); + task.height = .1; + task.width = 1; + task.put(VisualizationTask.META_NODETAIL, true); + it.visualizations.add(task); + master.subitems.add(it); + } + // Labels on left + for(int d2 = 2; d2 <= dmax; d2++) { + PlotItem it = new PlotItem(0, d2 - 2, .1, 1, null); + final VisualizationTask task = new VisualizationTask("", null, null, new LabelVisFactory(DatabaseUtil.getColumnLabel(rel, d2), true)); + task.height = 1; + task.width = .1; + task.put(VisualizationTask.META_NODETAIL, true); + it.visualizations.add(task); + master.subitems.add(it); + } + } + + layout.add(master); + } + return layout; + } + + @Override + public String getLongName() { + return "Scatterplot"; + } + + @Override + public String getShortName() { + return "scatterplot"; + } + + /** + * The relation we project. + * + * @return Relation + */ + public Relation<V> getRelation() { + return rel; + } +}
\ No newline at end of file diff --git a/src/de/lmu/ifi/dbs/elki/visualization/projector/package-info.java b/src/de/lmu/ifi/dbs/elki/visualization/projector/package-info.java new file mode 100644 index 00000000..5975089c --- /dev/null +++ b/src/de/lmu/ifi/dbs/elki/visualization/projector/package-info.java @@ -0,0 +1,26 @@ +/** + * <p>Projectors are responsible for finding appropriate projections for data relations.</p> + */ +/* +This file is part of ELKI: +Environment for Developing KDD-Applications Supported by Index-Structures + +Copyright (C) 2011 +Ludwig-Maximilians-Universität München +Lehr- und Forschungseinheit für Datenbanksysteme +ELKI Development Team + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +package de.lmu.ifi.dbs.elki.visualization.projector;
\ No newline at end of file |