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 xMin = 0;
    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(axis.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.