Example: Daily Carbon Monoxide Levels by Time of Day

A surface plot is rendered to show the carbon monoxide levels in a metropolitan area over the course of a year by time of day.


import com.imsl.chart3d.*;
import com.imsl.chart.Colormap;
import com.imsl.io.*;
import java.awt.Color;
import java.io.*;
import java.sql.SQLException;
import java.util.GregorianCalendar;

// CO surface shaded by temperature
public class SurfaceEx2 extends JFrameChart3D {

    static private final int xMax = 365;
    static private final int yMin = 0;
    static private final int yMax = 144;

    private double temp[][];
    private double co[][];

    private double tempMin, tempMax;

    private Colormap colormap = Colormap.SPECTRAL;

    // Creates new form COSurface 
    public SurfaceEx2() throws IOException, SQLException {
        temp = readData("temp.csv");
        co = readData("co.csv");

        tempMin = temp[0][0];
        tempMax = temp[0][0];
        for (int i = 0; i < xMax; i++) {
            for (int j = 0; j < yMax; j++) {
                tempMin = Math.min(temp[i][j], tempMin);
                tempMax = Math.max(temp[i][j], tempMax);
            }
        }

        Chart3D chart = getChart3D();
        chart.getBackground().setFillColor("lightyellow");
        AxisXYZ axis = new AxisXYZ(chart);
        axis.setAxisTitlePosition(AxisXYZ.AXIS_TITLE_PARALLEL);

        axis.getAxisX().getAxisTitle().setTitle("Day of Year");
        final GregorianCalendar initialDate = new GregorianCalendar(2000,
                GregorianCalendar.JANUARY, 1);
        axis.getAxisX().setAutoscaleOutput(0);
        GregorianCalendar lastDate = (GregorianCalendar) initialDate.clone();
        lastDate.add(GregorianCalendar.DATE, 365);
        axis.getAxisX().setWindow(initialDate.getTimeInMillis(),
                lastDate.getTimeInMillis());
        axis.getAxisX().setTextFormat(new java.text.SimpleDateFormat("MMM"));

        axis.getAxisY().getAxisTitle().setTitle("Time of Day");
        axis.getAxisY().setAutoscaleOutput(0);
        axis.getAxisY().setWindow(yMin, yMax);
        String labelsY[] = {"0:00", "6:00", "12:00", "18:00", "24:00"};
        axis.getAxisY().getAxisLabel().setLabels(labelsY);

        axis.getAxisZ().getAxisTitle().setTitle("CO");
        axis.getAxisZ().getAxisTitle().
                setAxisTitlePosition(axis.AXIS_TITLE_AT_END);
        axis.getAxisZ().setTextFormat("0.0");

        GregorianCalendar date = (GregorianCalendar) initialDate.clone();
        double x[] = new double[xMax];
        for (int i = 0; i < xMax; i++) {
            x[i] = date.getTimeInMillis();
            date.add(GregorianCalendar.DATE, 1);
        }

        double y[] = new double[yMax];
        for (int j = 0; j < yMax; j++) {
            y[j] = j - 1;
        }

        Color color[][] = new Color[xMax][yMax];
        for (int i = 0; i < xMax; i++) {
            for (int j = 0; j < yMax; j++) {
                double t = (tempMax - temp[i][j]) / (tempMax - tempMin);
                color[i][j] = colormap.color(t);
            }
        }

        Surface surface = new Surface(axis, x, y, co, color);
        surface.setSurfaceType(Surface.SURFACE_TYPE_NICEST);
        int nTicks = 10;
        double ticks[] = new double[nTicks];
        for (int i = 0; i < nTicks; i++) {
            ticks[i] = tempMax - i * (tempMax - tempMin) / (nTicks - 1);
        }
        ColormapLegend colormapLegend
                = new ColormapLegend(chart, colormap, ticks);
        colormapLegend.setPosition(-1, 10);
        colormapLegend.setTitle("Temperature");

        setSize(375, 375);
        render();
    }

    static private double[][] readData(String name)
            throws IOException, SQLException {
        InputStream is = SurfaceEx2.class.getResourceAsStream(name);
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        FlatFile ff = new FlatFile(br);
        double data[][] = new double[xMax][yMax];
        for (int j = 0; j < yMax; j++) {
            if (!ff.next()) {
                throw new IOException("Error in file " + name);
            }
            for (int i = 0; i < xMax; i++) {
                data[i][j] = ff.getDouble(i + 1);
            }
        }
        is.close();
        return data;
    }

    public static void main(String args[]) throws IOException, SQLException {
        new SurfaceEx2().setVisible(true);
    }
}

Output

Link to Java source.