view yetilab/plot/plot.yeti @ 131:70eaf374a1b5

Make charts non-animated; add a list of nice colours
author Chris Cannam
date Mon, 22 Apr 2013 10:24:44 +0100
parents aef0fbc65f16
children f268b2982ed4
line wrap: on
line source
module yetilab.plot.plot;

import org.jzy3d.plot3d.builder: Mapper;
import org.jzy3d.plot3d.text.drawable: DrawableTextBillboard, DrawableTextBitmap;
import org.jzy3d.maths: Range, Coord3d;
import org.jzy3d.plot3d.primitives: Shape, HistogramBar, FlatLine2d, Polygon, Quad, Point;
import org.jzy3d.plot3d.primitives.axes.layout.providers: StaticTickProvider;
import org.jzy3d.plot3d.primitives.axes.layout.renderers: TickLabelMap;
import org.jzy3d.chart: Chart, ChartLauncher;
import org.jzy3d.plot3d.builder: Builder;
import org.jzy3d.plot3d.builder.concrete: OrthonormalGrid;
import org.jzy3d.colors.colormaps: ColorMapRainbow;
import org.jzy3d.colors: ColorMapper, Color;
import org.jzy3d.plot3d.rendering.canvas: Quality;
import org.jzy3d.plot3d.rendering.view.modes: ViewPositionMode;

chartColours = [
    new Color(161, 54, 2), // red
    new Color(207, 228, 148), // grey-green
    new Color(82, 126, 154), // dark steel blue
    new Color(251, 116, 43), // light red
    new Color(126, 33, 28), // dried blood!
    new Color(21, 183, 197), // light blue
    new Color(188, 13, 207), // mid purple
    new Color(200, 125, 234), // light purple
];    

newMatrixMapper matrix =
   (class MMapper extends Mapper
        double f(double x, double y)
            result = matrix.getAt y x;
            println "f(\(x),\(y)) -> \(result)";
            result
    end;
    new MMapper());

newMatrixLogMapper matrix =
   (class MMapper extends Mapper
        double f(double x, double y)
            ln (matrix.getAt y x)
    end;
    new MMapper());

newMapper mapFunction =
   (class FMapper extends Mapper
        double f(double x, double y)
            mapFunction x y
    end;
    new FMapper());

plotMatrix matrix =
   (mapper = newMatrixMapper matrix;
    size = matrix.size;
    xrange = new Range(0, size.columns - 1);
    yrange = new Range(0, size.rows - 1);
    grid = new OrthonormalGrid(xrange, size.columns, yrange, size.rows);
    println "Matrix size: \(size)";
    surface = Builder#buildOrthonormal(grid, mapper); //??? big?
    println "Z Bounds: \(surface#getBounds()#getZmin()) -> \(surface#getBounds()#getZmax())";
    surface#setFaceDisplayed(true);
    surface#setWireframeDisplayed(true);
    surface#setWireframeColor(Color#BLACK);
//    chart = new Chart(Quality#Fastest, "swing");
    chart = new Chart(Quality#Nicest);
    chart#getScene()#getGraph()#add(surface);
    ChartLauncher#openChart(chart);
    ());

plotBarChart keys unit values =
   (quality = Quality#Nicest;
    quality#setAnimated(false);
    chart = new Chart(quality);
    var n = 0;
    scene = chart#getScene();
    ticks = new float[length keys];
    tickLabels = new TickLabelMap();
    for keys do k:
        bar = new HistogramBar();
        bar#setData(new Coord3d(n, 0, 0), values[k], 0.45, Color#random());
        bar#setWireframeDisplayed(false);
        scene#add(bar);
        ticks[n] := n;
        tickLabels#register(n, k);
        n := n + 1;
    done;
    chart#getView()#setViewPoint(new Coord3d(pi/2, 0, 0));
    axes = chart#getAxeLayout();
    axes#setXAxeLabelDisplayed(false);
    axes#setYAxeLabelDisplayed(false);
    axes#setZAxeLabelDisplayed(true);
    axes#setZAxeLabel(unit);
    axes#setXTickProvider(new StaticTickProvider(ticks));
    axes#setXTickRenderer(tickLabels);
    axes#setYTickLabelDisplayed(false);
    ChartLauncher#openChart(chart);
    ());

plotLines xkeys unit values =
   (quality = Quality#Nicest;
    quality#setAnimated(false);
    chart = new Chart(quality);
    scene = chart#getScene();
    keys = keys values;
    n = length xkeys;
    var z = 0;
    for keys do k:
        v = values[k];
        x = new float[n];
        y = new float[n];
        var i = 0;
        for xkeys do xk:
            x[i] := i;
            y[i] := if xk in v then v[xk] else 0 fi;
            i := i + 1;
        done;
        line = new FlatLine2d(x, y, z);
        line#setWireframeDisplayed(true);
        line#setWireframeColor(Color#random());
        line#setWireframeWidth(2);
        line#setFaceDisplayed(false);
        scene#add(line);
        z := z + 1;
    done;
    chart#getView()#setViewPoint(new Coord3d(0, 0, 0));
    axes = chart#getAxeLayout();
    axes#setXAxeLabelDisplayed(false);
    axes#setYAxeLabelDisplayed(false);
    axes#setZAxeLabelDisplayed(true);
    axes#setZAxeLabel(unit);
    axes#setYTickLabelDisplayed(false);
    ChartLauncher#openChart(chart);
    ());

stack keys xkeys values normalised =
   (stacked = mapIntoHash id \(mapIntoHash id \{ y0 = 0, y1 = 0 } xkeys) keys;
    prev = mapIntoHash id \0 xkeys;
    valueOf k xk = if xk in values[k] then values[k][xk] else 0 fi;
    for xkeys do xk:
        total = sum (map do k: valueOf k xk done keys);
        for keys do k:
            value =
                if normalised and total > 0
                then (valueOf k xk) / total
                else (valueOf k xk)
                fi;
            height = prev[xk] + value;
            stacked[k][xk] := { y0 = prev[xk], y1 = height };
            prev[xk] := height;
        done;
    done;
    stacked);

plotStacked keys xkeys unit values normalised =
   (quality = Quality#Nicest;
    quality#setAnimated(false);
    chart = new Chart(quality);
    scene = chart#getScene();
    stacked = stack keys xkeys values normalised;
    var z = 0;
    newRect x y0 y1 z colour is number -> number -> number -> number -> ~Color -> 'a =
       (poly = new Quad();
        poly#add(new Point(new Coord3d(x + 0.5, z, y0)));
        poly#add(new Point(new Coord3d(x + 0.5, z, y1)));
        poly#add(new Point(new Coord3d(x - 0.5, z, y1)));
        poly#add(new Point(new Coord3d(x - 0.5, z, y0)));
        poly#setWireframeDisplayed(true);
        poly#setWireframeColor(colour);
        poly#setFaceDisplayed(true);
        poly#setColor(colour);
        poly);
    var ty = 0;
    for keys do k:
        ranges = stacked[k];
        var x = 0;
        c = Color#random();
        for xkeys do xk:
            rect = newRect x ranges[xk].y0 ranges[xk].y1 z c;
            scene#add(rect);
            x := x + 1;
        done;
        text = new DrawableTextBitmap(k, new Coord3d(-5, z, ty), c);
        scene#add(text);
        z := z - 1;
        ty := ty + 0.1;
    done;
    chart#getView()#setViewPoint(new Coord3d(-pi/2, 0, 0));
    axes = chart#getAxeLayout();
    axes#setXAxeLabelDisplayed(false);
    axes#setYAxeLabelDisplayed(false);
    axes#setZAxeLabelDisplayed(true);
    axes#setZAxeLabel(unit);
    axes#setYTickLabelDisplayed(false);
    ChartLauncher#openChart(chart);
    ());

plotStructure structure =
    case structure of
    Grid matrix:
        plotMatrix matrix;
    //!!!
    _: failWith "Cannot plot this structure (only grids implemented so far)";
    esac;

{
    newMatrixMapper,
    newMatrixLogMapper,
    newMapper,
    plotMatrix, 
    plotBarChart,
    plotLines,
    stack,
    plotStacked,
    plotStructure,
}