diff options
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj')
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java | 2 | ||||
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisualization.java | 16 | ||||
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java | 3 | ||||
-rw-r--r-- | src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/XYCurveVisFactory.java (renamed from src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/CurveVisFactory.java) | 170 |
4 files changed, 77 insertions, 114 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java index 05d9038c..5b58e842 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/ClusterEvaluationVisFactory.java @@ -59,7 +59,7 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; * * @apiviz.stereotype factory * @apiviz.uses StaticVisualization oneway - - «create» - * @apiviz.has EvaluateClustering.ScoreResult oneway - - visualizes + * @apiviz.has de.lmu.ifi.dbs.elki.evaluation.clustering.EvaluateClustering.ScoreResult oneway - - visualizes */ public class ClusterEvaluationVisFactory extends AbstractVisFactory { /** diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisualization.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisualization.java index 15c50a39..62a4fb5c 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisualization.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/KeyVisualization.java @@ -23,7 +23,7 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.Iterator; +import java.util.Collection; import java.util.List; import org.apache.batik.util.SVGConstants; @@ -98,13 +98,14 @@ public class KeyVisualization extends AbstractVisualization { SVGPlot svgp = task.getPlot(); final List<Cluster<Model>> allcs = clustering.getAllClusters(); - MarkerLibrary ml = context.getStyleLibrary().markers(); + StyleLibrary style = context.getStyleLibrary(); + MarkerLibrary ml = style.markers(); layer = svgp.svgElement(SVGConstants.SVG_G_TAG); // Add a label for the clustering. { Element label = svgp.svgText(0.1, 0.7, clustering.getLongName()); - label.setAttribute(SVGConstants.SVG_STYLE_ATTRIBUTE, "font-size: 0.4"); + label.setAttribute(SVGConstants.SVG_STYLE_ATTRIBUTE, "font-size: 0.4; fill: "+style.getTextColor(StyleLibrary.DEFAULT)); layer.appendChild(label); } @@ -113,7 +114,7 @@ public class KeyVisualization extends AbstractVisualization { for(Cluster<Model> c : allcs) { ml.useMarker(svgp, layer, 0.3, i + 1.5, i, 0.3); Element label = svgp.svgText(0.7, i + 1.7, c.getNameAutomatic()); - label.setAttribute(SVGConstants.SVG_STYLE_ATTRIBUTE, "font-size: 0.6"); + label.setAttribute(SVGConstants.SVG_STYLE_ATTRIBUTE, "font-size: 0.6; fill: "+style.getTextColor(StyleLibrary.DEFAULT)); layer.appendChild(label); i++; } @@ -146,7 +147,7 @@ public class KeyVisualization extends AbstractVisualization { int rows = i + 2; int cols = Math.max(6, (int) (rows * task.getHeight() / task.getWidth())); - final double margin = context.getStyleLibrary().getSize(StyleLibrary.MARGIN); + final double margin = style.getSize(StyleLibrary.MARGIN); final String transform = SVGUtil.makeMarginTransform(task.getWidth(), task.getHeight(), cols, rows, margin / StyleLibrary.SCALE); SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform); } @@ -171,9 +172,8 @@ public class KeyVisualization extends AbstractVisualization { @Override public void processNewResult(HierarchicalResult baseResult, Result newResult) { // Find clusterings we can visualize: - Iterator<Clustering<?>> clusterings = ResultUtil.filteredResults(newResult, Clustering.class); - while(clusterings.hasNext()) { - Clustering<?> c = clusterings.next(); + Collection<Clustering<?>> clusterings = ResultUtil.filterResults(newResult, Clustering.class); + for (Clustering<?> c : clusterings) { if(c.getAllClusters().size() > 0) { final VisualizationTask task = new VisualizationTask(NAME, c, null, this); task.width = 1.0; diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java index 5bbc698c..2d726257 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/SettingsVisFactory.java @@ -32,7 +32,6 @@ 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.SettingsResult; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ClassParameter; import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.Parameter; import de.lmu.ifi.dbs.elki.utilities.pairs.Pair; @@ -138,7 +137,7 @@ public class SettingsVisFactory extends AbstractVisFactory { @Override public void processNewResult(HierarchicalResult baseResult, Result newResult) { - final IterableIterator<SettingsResult> settingsResults = ResultUtil.filteredResults(newResult, SettingsResult.class); + Collection<SettingsResult> settingsResults = ResultUtil.filterResults(newResult, SettingsResult.class); for(SettingsResult sr : settingsResults) { final VisualizationTask task = new VisualizationTask(NAME, sr, null, this); task.width = 1.0; diff --git a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/CurveVisFactory.java b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/XYCurveVisFactory.java index e12a392a..507de376 100644 --- a/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/CurveVisFactory.java +++ b/src/de/lmu/ifi/dbs/elki/visualization/visualizers/visunproj/XYCurveVisFactory.java @@ -23,25 +23,21 @@ package de.lmu.ifi.dbs.elki.visualization.visualizers.visunproj; along with this program. If not, see <http://www.gnu.org/licenses/>. */ -import java.util.Collection; -import java.util.Iterator; +import java.util.ArrayList; import org.apache.batik.util.SVGConstants; import org.w3c.dom.Element; -import de.lmu.ifi.dbs.elki.evaluation.roc.ComputeROCCurve; -import de.lmu.ifi.dbs.elki.evaluation.roc.ComputeROCCurve.ROCResult; +import de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierROCCurve; +import de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierROCCurve.ROCResult; +import de.lmu.ifi.dbs.elki.evaluation.outlier.OutlierPrecisionRecallCurve.PRCurve; import de.lmu.ifi.dbs.elki.logging.LoggingUtil; -import de.lmu.ifi.dbs.elki.math.DoubleMinMax; +import de.lmu.ifi.dbs.elki.math.geometry.XYCurve; import de.lmu.ifi.dbs.elki.math.scales.LinearScale; import de.lmu.ifi.dbs.elki.result.HierarchicalResult; -import de.lmu.ifi.dbs.elki.result.IterableResult; import de.lmu.ifi.dbs.elki.result.Result; import de.lmu.ifi.dbs.elki.result.ResultUtil; import de.lmu.ifi.dbs.elki.utilities.FormatUtil; -import de.lmu.ifi.dbs.elki.utilities.iterator.AbstractFilteredIterator; -import de.lmu.ifi.dbs.elki.utilities.iterator.IterableIterator; -import de.lmu.ifi.dbs.elki.utilities.pairs.DoubleDoublePair; import de.lmu.ifi.dbs.elki.visualization.VisualizationTask; import de.lmu.ifi.dbs.elki.visualization.VisualizerContext; import de.lmu.ifi.dbs.elki.visualization.css.CSSClass; @@ -62,13 +58,13 @@ import de.lmu.ifi.dbs.elki.visualization.visualizers.Visualization; * * @apiviz.stereotype factory * @apiviz.uses StaticVisualization oneway - - «create» - * @apiviz.has IterableResult oneway - - visualizes + * @apiviz.has XYCurve oneway - - visualizes */ -public class CurveVisFactory extends AbstractVisFactory { +public class XYCurveVisFactory extends AbstractVisFactory { /** * Name for this visualizer. */ - private static final String NAME = "Curve"; + private static final String NAME = "XYCurve"; /** * SVG class name for plot line @@ -76,9 +72,14 @@ public class CurveVisFactory extends AbstractVisFactory { private static final String SERIESID = "series"; /** + * Axis labels + */ + private static final String CSS_AXIS_LABEL = "xy-axis-label"; + + /** * Constructor, Parameterizable style - does nothing. */ - public CurveVisFactory() { + public XYCurveVisFactory() { super(); } @@ -86,7 +87,7 @@ public class CurveVisFactory extends AbstractVisFactory { public Visualization makeVisualization(VisualizationTask task) { VisualizerContext context = task.getContext(); SVGPlot svgp = task.getPlot(); - IterableResult<DoubleDoublePair> curve = task.getResult(); + XYCurve curve = task.getResult(); setupCSS(context, svgp); double scale = StyleLibrary.SCALE; @@ -98,19 +99,13 @@ public class CurveVisFactory extends AbstractVisFactory { SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform); // determine scaling - DoubleMinMax minmaxx = new DoubleMinMax(); - DoubleMinMax minmaxy = new DoubleMinMax(); - for(DoubleDoublePair pair : curve) { - minmaxx.put(pair.first); - minmaxy.put(pair.second); - } - LinearScale scalex = new LinearScale(minmaxx.getMin(), minmaxx.getMax()); - LinearScale scaley = new LinearScale(minmaxy.getMin(), minmaxy.getMax()); + LinearScale scalex = new LinearScale(curve.getMinx(), curve.getMaxx()); + LinearScale scaley = new LinearScale(curve.getMiny(), curve.getMaxy()); // plot the line SVGPath path = new SVGPath(); - for(DoubleDoublePair pair : curve) { - final double x = scalex.getScaled(pair.first); - final double y = 1 - scaley.getScaled(pair.second); + for(XYCurve.Itr iterator = curve.iterator(); iterator.valid(); iterator.advance()) { + final double x = scalex.getScaled(iterator.getX()); + final double y = 1 - scaley.getScaled(iterator.getY()); path.drawTo(sizex * x, sizey * y); } Element line = path.makeElement(svgp); @@ -124,35 +119,44 @@ public class CurveVisFactory extends AbstractVisFactory { catch(CSSNamingConflict e) { LoggingUtil.exception(e); } + // Add axis labels + { + Element labelx = svgp.svgText(sizex / 2, sizey + margin * .9, curve.getLabelx()); + SVGUtil.setCSSClass(labelx, CSS_AXIS_LABEL); + layer.appendChild(labelx); + Element labely = svgp.svgText(margin * -.8, sizey * .5, curve.getLabely()); + SVGUtil.setCSSClass(labely, CSS_AXIS_LABEL); + SVGUtil.setAtt(labely, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, "rotate(-90,"+FormatUtil.NF6.format(margin * -.8)+","+FormatUtil.NF6.format(sizey * .5)+")"); + layer.appendChild(labely); + } // Add AUC value when found if(curve instanceof ROCResult) { - Collection<String> header = ((ROCResult) curve).getHeader(); - for(String str : header) { - String[] parts = str.split(":\\s*"); - if(parts[0].equals(ComputeROCCurve.ROCAUC_LABEL) && parts.length == 2) { - double rocauc = Double.parseDouble(parts[1]); - StyleLibrary style = context.getStyleLibrary(); - CSSClass cls = new CSSClass(svgp, "unmanaged"); - String lt = "ROC AUC: " + FormatUtil.NF8.format(rocauc); - double fontsize = style.getTextSize("curve.labels"); - cls.setStatement(SVGConstants.CSS_FONT_SIZE_PROPERTY, SVGUtil.fmt(fontsize)); - cls.setStatement(SVGConstants.CSS_FILL_PROPERTY, style.getTextColor("curve.labels")); - cls.setStatement(SVGConstants.CSS_FONT_FAMILY_PROPERTY, style.getFontFamily("curve.labels")); - if(rocauc <= 0.5) { - Element auclbl = svgp.svgText(sizex * 0.95, sizey * 0.95, lt); - SVGUtil.setAtt(auclbl, SVGConstants.SVG_STYLE_ATTRIBUTE, cls.inlineCSS()); - // SVGUtil.setAtt(auclbl, SVGConstants.SVG_TEXT_ANCHOR_ATTRIBUTE, - // SVGConstants.SVG_START_VALUE); - layer.appendChild(auclbl); - } - else { - Element auclbl = svgp.svgText(sizex * 0.95, sizey * 0.95, lt); - SVGUtil.setAtt(auclbl, SVGConstants.SVG_STYLE_ATTRIBUTE, cls.inlineCSS()); - SVGUtil.setAtt(auclbl, SVGConstants.SVG_TEXT_ANCHOR_ATTRIBUTE, SVGConstants.SVG_END_VALUE); - layer.appendChild(auclbl); - } - } + double rocauc = ((ROCResult) curve).getAUC(); + String lt = OutlierROCCurve.ROCAUC_LABEL + ": " + FormatUtil.NF8.format(rocauc); + if(rocauc <= 0.5) { + Element auclbl = svgp.svgText(sizex * 0.5, sizey * 0.10, lt); + SVGUtil.setCSSClass(auclbl, CSS_AXIS_LABEL); + layer.appendChild(auclbl); + } + else { + Element auclbl = svgp.svgText(sizex * 0.5, sizey * 0.95, lt); + SVGUtil.setCSSClass(auclbl, CSS_AXIS_LABEL); + layer.appendChild(auclbl); + } + } + if(curve instanceof PRCurve) { + double prauc = ((PRCurve) curve).getAUC(); + String lt = PRCurve.PRAUC_LABEL + ": " + FormatUtil.NF8.format(prauc); + if(prauc <= 0.5) { + Element auclbl = svgp.svgText(sizex * 0.5, sizey * 0.10, lt); + SVGUtil.setCSSClass(auclbl, CSS_AXIS_LABEL); + layer.appendChild(auclbl); + } + else { + Element auclbl = svgp.svgText(sizex * 0.5, sizey * 0.95, lt); + SVGUtil.setCSSClass(auclbl, CSS_AXIS_LABEL); + layer.appendChild(auclbl); } } @@ -166,66 +170,26 @@ public class CurveVisFactory extends AbstractVisFactory { * @param svgp Plot */ private void setupCSS(VisualizerContext context, SVGPlot svgp) { + StyleLibrary style = context.getStyleLibrary(); CSSClass csscls = new CSSClass(this, SERIESID); // csscls.setStatement(SVGConstants.SVG_STROKE_WIDTH_ATTRIBUTE, "0.2%"); csscls.setStatement(SVGConstants.SVG_FILL_ATTRIBUTE, SVGConstants.SVG_NONE_VALUE); - context.getStyleLibrary().lines().formatCSSClass(csscls, 0, context.getStyleLibrary().getLineWidth(StyleLibrary.PLOT)); + style.lines().formatCSSClass(csscls, 0, style.getLineWidth(StyleLibrary.XYCURVE)); svgp.addCSSClassOrLogError(csscls); - } - - /** - * Filter to only retrieve double-double-pair results. - * - * @author Erich Schubert - * - * @apiviz.exclude - */ - class CurveFilter extends AbstractFilteredIterator<IterableResult<?>, IterableResult<DoubleDoublePair>> implements IterableIterator<IterableResult<DoubleDoublePair>> { - /** - * Parent iterator to use - */ - Iterator<IterableResult<?>> parent; - - /** - * Constructor. - * - * @param parent Parent iterator to decorate. - */ - public CurveFilter(Iterator<IterableResult<?>> parent) { - super(); - this.parent = parent; - } - - @Override - protected Iterator<IterableResult<?>> getParentIterator() { - return parent; - } - - @Override - protected IterableResult<DoubleDoublePair> testFilter(IterableResult<?> nextobj) { - Iterator<?> iterator = nextobj.iterator(); - if(iterator.hasNext()) { - Object o = iterator.next(); - if(o instanceof DoubleDoublePair) { - @SuppressWarnings("unchecked") - final IterableResult<DoubleDoublePair> ret = (IterableResult<DoubleDoublePair>) nextobj; - return ret; - } - } - return null; - } - - @Override - public Iterator<IterableResult<DoubleDoublePair>> iterator() { - return this; - } + // Axis label + CSSClass label = new CSSClass(this, CSS_AXIS_LABEL); + label.setStatement(SVGConstants.CSS_FILL_PROPERTY, style.getTextColor(StyleLibrary.XYCURVE)); + label.setStatement(SVGConstants.CSS_FONT_FAMILY_PROPERTY, style.getFontFamily(StyleLibrary.XYCURVE)); + label.setStatement(SVGConstants.CSS_FONT_SIZE_PROPERTY, style.getTextSize(StyleLibrary.XYCURVE)); + label.setStatement(SVGConstants.CSS_TEXT_ANCHOR_PROPERTY, SVGConstants.CSS_MIDDLE_VALUE); + svgp.addCSSClassOrLogError(label); + svgp.updateStyleElement(); } @Override public void processNewResult(HierarchicalResult baseResult, Result result) { - final IterableIterator<IterableResult<?>> iterableResults = ResultUtil.filteredResults(result, IterableResult.class); - final IterableIterator<IterableResult<DoubleDoublePair>> curves = new CurveFilter(iterableResults); - for (IterableResult<DoubleDoublePair> curve : curves) { + final ArrayList<XYCurve> curves = ResultUtil.filterResults(result, XYCurve.class); + for(XYCurve curve : curves) { final VisualizationTask task = new VisualizationTask(NAME, curve, null, this); task.width = 1.0; task.height = 1.0; |