use of de.lmu.ifi.dbs.elki.visualization.svg.SVGPath in project elki by elki-project.
the class HistogramVisualization method makeVisualization.
@Override
public Visualization makeVisualization(VisualizerContext context, VisualizationTask task, VisualizationPlot plot, double width, double height, Projection proj) {
HistogramResult curve = task.getResult();
final StyleLibrary style = context.getStyleLibrary();
final double sizex = StyleLibrary.SCALE;
final double sizey = StyleLibrary.SCALE * height / width;
final double margin = style.getSize(StyleLibrary.MARGIN);
Element layer = SVGUtil.svgElement(plot.getDocument(), SVGConstants.SVG_G_TAG);
final String transform = SVGUtil.makeMarginTransform(width, height, sizex, sizey, margin);
SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform);
// find maximum, determine step size
int dim = -1;
DoubleMinMax xminmax = new DoubleMinMax();
DoubleMinMax yminmax = new DoubleMinMax();
for (double[] point : curve) {
xminmax.put(point[0]);
dim = dim < point.length ? point.length : dim;
for (int i = 1; i < point.length; i++) {
yminmax.put(point[i]);
}
}
// Minimum should always start at 0 for histograms
yminmax.put(0.0);
// remove one dimension which are the x values.
dim = dim - 1;
int size = curve.size();
double range = xminmax.getMax() - xminmax.getMin();
double binwidth = range / (size - 1);
LinearScale xscale = new LinearScale(xminmax.getMin() - binwidth * .49999, xminmax.getMax() + binwidth * .49999);
LinearScale yscale = new LinearScale(yminmax.getMin(), yminmax.getMax());
SVGPath[] path = new SVGPath[dim];
for (int i = 0; i < dim; i++) {
path[i] = new SVGPath(sizex * xscale.getScaled(xminmax.getMin() - binwidth * .5), sizey);
}
// draw curves.
for (double[] point : curve) {
for (int d = 0; d < dim; d++) {
path[d].lineTo(sizex * (xscale.getScaled(point[0] - binwidth * .5)), sizey * (1 - yscale.getScaled(point[d + 1])));
path[d].lineTo(sizex * (xscale.getScaled(point[0] + binwidth * .5)), sizey * (1 - yscale.getScaled(point[d + 1])));
}
}
// close all histograms
for (int i = 0; i < dim; i++) {
path[i].lineTo(sizex * xscale.getScaled(xminmax.getMax() + binwidth * .5), sizey);
}
// add axes
try {
SVGSimpleLinearAxis.drawAxis(plot, layer, yscale, 0, sizey, 0, 0, SVGSimpleLinearAxis.LabelStyle.LEFTHAND, style);
SVGSimpleLinearAxis.drawAxis(plot, layer, xscale, 0, sizey, sizex, sizey, SVGSimpleLinearAxis.LabelStyle.RIGHTHAND, style);
} catch (CSSNamingConflict e) {
LoggingUtil.exception(e);
}
// Setup line styles and insert lines.
ColorLibrary cl = style.getColorSet(StyleLibrary.PLOT);
for (int d = 0; d < dim; d++) {
CSSClass csscls = new CSSClass(this, SERIESID + "_" + d);
csscls.setStatement(SVGConstants.SVG_FILL_ATTRIBUTE, SVGConstants.SVG_NONE_VALUE);
csscls.setStatement(SVGConstants.SVG_STROKE_ATTRIBUTE, cl.getColor(d));
csscls.setStatement(SVGConstants.SVG_STROKE_WIDTH_ATTRIBUTE, style.getLineWidth(StyleLibrary.PLOT));
plot.addCSSClassOrLogError(csscls);
Element line = path[d].makeElement(plot);
line.setAttribute(SVGConstants.SVG_CLASS_ATTRIBUTE, csscls.getName());
layer.appendChild(line);
}
return new StaticVisualizationInstance(context, task, plot, width, height, layer);
}
use of de.lmu.ifi.dbs.elki.visualization.svg.SVGPath in project elki by elki-project.
the class DistanceFunctionVisualization method drawCosine.
/**
* Visualizes Cosine and ArcCosine distance functions
*
* @param svgp SVG Plot
* @param proj Visualization projection
* @param mid mean vector
* @param angle Opening angle in radians
* @return path element
*/
public static Element drawCosine(SVGPlot svgp, Projection2D proj, NumberVector mid, double angle) {
// Project origin
double[] pointOfOrigin = proj.fastProjectDataToRenderSpace(new double[proj.getInputDimensionality()]);
// direction of the selected Point
double[] selPoint = proj.fastProjectDataToRenderSpace(mid);
double[] range1, range2;
{
// Rotation plane:
double[] p1 = proj.fastProjectRenderToDataSpace(selPoint[0] + 10, selPoint[1]);
double[] p2 = proj.fastProjectRenderToDataSpace(selPoint[0], selPoint[1] + 10);
double[] pm = mid.toArray();
// Compute relative vectors
minusEquals(p1, pm);
minusEquals(p2, pm);
// Scale p1 and p2 to unit length:
timesEquals(p1, 1. / euclideanLength(p1));
timesEquals(p2, 1. / euclideanLength(p2));
{
double test = scalarProduct(p1, p2);
if (Math.abs(test) > 1E-10) {
LoggingUtil.warning("Projection does not seem to be orthogonal?");
}
}
// Project onto p1, p2:
double l1 = scalarProduct(pm, p1), l2 = scalarProduct(pm, p2);
// Rotate projection by + and - angle
// Using sin(-x) = -sin(x) and cos(-x)=cos(x)
// To return cosine
final DoubleWrapper tmp = new DoubleWrapper();
final double sangle = FastMath.sinAndCos(angle, tmp), cangle = tmp.value;
double r11 = +cangle * l1 - sangle * l2, r12 = +sangle * l1 + cangle * l2;
double r21 = +cangle * l1 + sangle * l2, r22 = -sangle * l1 + cangle * l2;
// Build rotated vectors - remove projected component, add rotated
// component:
double[] r1 = copy(pm), r2 = copy(pm);
plusTimesEquals(r1, p1, -l1 + r11);
plusTimesEquals(r1, p2, -l2 + r12);
plusTimesEquals(r2, p1, -l1 + r21);
plusTimesEquals(r2, p2, -l2 + r22);
// Project to render space:
range1 = proj.fastProjectDataToRenderSpace(r1);
range2 = proj.fastProjectDataToRenderSpace(r2);
}
// Continue lines to viewport.
{
CanvasSize viewport = proj.estimateViewport();
minusEquals(range1, pointOfOrigin);
minusEquals(range2, pointOfOrigin);
timesEquals(range1, viewport.continueToMargin(pointOfOrigin, range1));
timesEquals(range2, viewport.continueToMargin(pointOfOrigin, range2));
plusEquals(range1, pointOfOrigin);
plusEquals(range2, pointOfOrigin);
// Go backwards into the other direction - the origin might not be in the
// viewport!
double[] start1 = minus(pointOfOrigin, range1);
double[] start2 = minus(pointOfOrigin, range2);
timesEquals(start1, viewport.continueToMargin(range1, start1));
timesEquals(start2, viewport.continueToMargin(range2, start2));
plusEquals(start1, range1);
plusEquals(start2, range2);
// TODO: add filled variant?
SVGPath path = new SVGPath();
path.moveTo(start1);
path.lineTo(range1);
path.moveTo(start2);
path.lineTo(range2);
return path.makeElement(svgp);
}
}
use of de.lmu.ifi.dbs.elki.visualization.svg.SVGPath in project elki by elki-project.
the class XYPlotVisualization method makeVisualization.
@Override
public Visualization makeVisualization(VisualizerContext context, VisualizationTask task, VisualizationPlot plot, double width, double height, Projection proj) {
XYPlot xyplot = task.getResult();
setupCSS(context, plot, xyplot);
final StyleLibrary style = context.getStyleLibrary();
final double sizex = StyleLibrary.SCALE;
final double sizey = StyleLibrary.SCALE * height / width;
final double margin = style.getSize(StyleLibrary.MARGIN);
Element layer = SVGUtil.svgElement(plot.getDocument(), SVGConstants.SVG_G_TAG);
final String transform = SVGUtil.makeMarginTransform(width, height, sizex, sizey, margin);
SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform);
// determine scaling
LinearScale scalex = new LinearScale(xyplot.getMinx(), xyplot.getMaxx());
LinearScale scaley = new LinearScale(xyplot.getMiny(), xyplot.getMaxy());
for (XYPlot.Curve curve : xyplot) {
// plot the line
SVGPath path = new SVGPath();
for (XYPlot.Curve.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(plot);
line.setAttribute(SVGConstants.SVG_CLASS_ATTRIBUTE, SERIESID + curve.getColor());
layer.appendChild(line);
}
// add axes
try {
SVGSimpleLinearAxis.drawAxis(plot, layer, scaley, 0, sizey, 0, 0, SVGSimpleLinearAxis.LabelStyle.LEFTHAND, style);
SVGSimpleLinearAxis.drawAxis(plot, layer, scalex, 0, sizey, sizex, sizey, SVGSimpleLinearAxis.LabelStyle.RIGHTHAND, style);
} catch (CSSNamingConflict e) {
LoggingUtil.exception(e);
}
// Add axis labels
{
Element labelx = plot.svgText(sizex * .5, sizey + margin * .9, xyplot.getLabelx());
SVGUtil.setCSSClass(labelx, CSS_AXIS_LABEL);
layer.appendChild(labelx);
Element labely = plot.svgText(margin * -.8, sizey * .5, xyplot.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);
}
return new StaticVisualizationInstance(context, task, plot, width, height, layer);
}
use of de.lmu.ifi.dbs.elki.visualization.svg.SVGPath in project elki by elki-project.
the class XYCurveVisualization method makeVisualization.
@Override
public Visualization makeVisualization(VisualizerContext context, VisualizationTask task, VisualizationPlot plot, double width, double height, Projection proj) {
XYCurve curve = task.getResult();
setupCSS(context, plot);
final StyleLibrary style = context.getStyleLibrary();
final double sizex = StyleLibrary.SCALE;
final double sizey = StyleLibrary.SCALE * height / width;
final double margin = style.getSize(StyleLibrary.MARGIN);
Element layer = SVGUtil.svgElement(plot.getDocument(), SVGConstants.SVG_G_TAG);
final String transform = SVGUtil.makeMarginTransform(width, height, sizex, sizey, margin);
SVGUtil.setAtt(layer, SVGConstants.SVG_TRANSFORM_ATTRIBUTE, transform);
// determine scaling
LinearScale scalex = new LinearScale(curve.getMinx(), curve.getMaxx());
LinearScale scaley = new LinearScale(curve.getMiny(), curve.getMaxy());
// plot the line
SVGPath path = new SVGPath();
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(plot);
line.setAttribute(SVGConstants.SVG_CLASS_ATTRIBUTE, SERIESID);
// add axes
try {
SVGSimpleLinearAxis.drawAxis(plot, layer, scaley, 0, sizey, 0, 0, SVGSimpleLinearAxis.LabelStyle.LEFTHAND, style);
SVGSimpleLinearAxis.drawAxis(plot, layer, scalex, 0, sizey, sizex, sizey, SVGSimpleLinearAxis.LabelStyle.RIGHTHAND, style);
} catch (CSSNamingConflict e) {
LoggingUtil.exception(e);
}
// Add axis labels
{
Element labelx = plot.svgText(sizex * .5, sizey + margin * .9, curve.getLabelx());
SVGUtil.setCSSClass(labelx, CSS_AXIS_LABEL);
layer.appendChild(labelx);
Element labely = plot.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) {
double rocauc = ((ROCResult) curve).getAUC();
String lt = OutlierROCCurve.ROCAUC_LABEL + ": " + FormatUtil.NF.format(rocauc);
if (rocauc <= 0.5) {
Element auclbl = plot.svgText(sizex * 0.5, sizey * 0.10, lt);
SVGUtil.setCSSClass(auclbl, CSS_AXIS_LABEL);
layer.appendChild(auclbl);
} else {
Element auclbl = plot.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 = OutlierPrecisionRecallCurve.PRAUC_LABEL + ": " + FormatUtil.NF.format(prauc);
if (prauc <= 0.5) {
Element auclbl = plot.svgText(sizex * 0.5, sizey * 0.10, lt);
SVGUtil.setCSSClass(auclbl, CSS_AXIS_LABEL);
layer.appendChild(auclbl);
} else {
Element auclbl = plot.svgText(sizex * 0.5, sizey * 0.95, lt);
SVGUtil.setCSSClass(auclbl, CSS_AXIS_LABEL);
layer.appendChild(auclbl);
}
}
layer.appendChild(line);
return new StaticVisualizationInstance(context, task, plot, width, height, layer);
}
Aggregations