A multivariate data set is charted. This example shows how multiple variables can be encoded into a single chart. The data set is from: Afifi, A.A. and S.P. Azen (1979), Statistical Analysis: A Computer Oriented Approach , Second Edition, Academic Press, New York.
Each observation in the data set is represented by a marker. The encoding of the variables into the chart is described in the following table:
Representation | Variable |
x -coordinate | Age (years) |
y -coordinate | Height (cm) |
z -coordinate | Initial Body Surface Area (m^2) |
Marker Type | Survival? |
Marker Size | Initial Mean Circulation Time (sec) |
Color | Initial Cardiac Index (liters/min-m^2) |
Min Pulse Size | Initial Hemoglobin (gm/100 ml) |
Max Pulse Size | Final Hemoglobin (gm/100 ml) |
Rotation Direction | Sex (Gender) |
import com.imsl.chart.Colormap; import com.imsl.chart3d.*; import com.imsl.io.*; import com.imsl.stat.Summary; import java.awt.Color; import java.io.*; import java.sql.ResultSetMetaData; import java.sql.*; import java.util.StringTokenizer; import javax.swing.JPanel; import javax.swing.JLabel; public class DataEx3 extends javax.swing.JFrame { static private final int nVariables = 34; static private final int nObs = 113; static private final Colormap colormap = Colormap.BLUE_GREEN_RED_YELLOW; static private final int ivarX = 1; // Age (years) static private final int ivarY = 2; // Height (cm) static private final int ivarZ = 11; // Initial Body Surface Area (m^2) static private final int ivarMarkerType = 4; // Survival? static private final int ivarMarkerSize = 14; // Initial Mean Circulation Time (sec) static private final int ivarMarkerColor = 12; // Initial Cardiac Index (liters/min-m^2) static private final int ivarMarkerPulseMin = 18; // Initial Hemoglobin (gm/100 ml) static private final int ivarMarkerPulseMax = 32; // Final Hemoglobin (gm/100 ml) static private final int ivarRotationAxis = 3; // Sex (Gender) private ResultSetMetaData meta; private JPanel jPanelLegend; public DataEx3() throws IOException, SQLException { InputStream is = DataEx3.class.getResourceAsStream("AfifiAzen.csv"); AfifiAzenReader reader = new AfifiAzenReader(is); double data[][] = reader.readData(); is.close(); Chart3D chart = new Chart3D(); AxisXYZ axis = new AxisXYZ(chart); axis.setAxisTitlePosition(axis.AXIS_TITLE_PARALLEL); meta = reader.getMetaData(); axis.getAxisX().getAxisTitle().setTitle(meta.getColumnName(ivarX+1)); axis.getAxisY().getAxisTitle().setTitle(meta.getColumnName(ivarY+1)); axis.getAxisZ().getAxisTitle().setTitle(meta.getColumnName(ivarZ+1)); int markerTypes[] = {Data.MARKER_TYPE_CUBE, Data.MARKER_TYPE_TETRAHEDRON}; double minMarkerSize = 0.0; double maxMarkerSize = 0.0; if (ivarMarkerSize >= 0) { Summary summary = getSummary(data, ivarMarkerSize); minMarkerSize = summary.getMinimum(); maxMarkerSize = summary.getMaximum(); } double minColor = 0.0; double maxColor = 0.0; if (ivarMarkerColor >= 0) { Summary summary = getSummary(data, ivarMarkerColor); minColor = summary.getMinimum(); maxColor = summary.getMaximum(); } double maxPulse = 0.0; if (ivarMarkerColor >= 0) { maxPulse = getSummary(data, ivarMarkerPulseMax).getMaximum(); } axis.setDataType(Data.DATA_TYPE_MARKER); for (int i = 0; i < data.length; i++) { double xp[] = {data[i][ivarX]}; double yp[] = {data[i][ivarY]}; double zp[] = {data[i][ivarZ]}; Data data3D = new Data(axis, xp, yp, zp); double size = (data[i][ivarMarkerSize]-minMarkerSize) / (maxMarkerSize-minMarkerSize); data3D.setMarkerSize(1.0 + size); double t = (data[i][ivarMarkerColor]-minColor) / (maxColor-minColor); data3D.setMarkerColor(colormap.color(t)); data3D.setMarkerPulsingMinimumScale(data[i][ivarMarkerPulseMin]/maxPulse); data3D.setMarkerPulsingMaximumScale(data[i][ivarMarkerPulseMax]/maxPulse); data3D.setMarkerPulsingCycle(1.0); double zaxis = (data[i][ivarRotationAxis] == 1 ? 1.0 : -1.0); data3D.setMarkerRotatingAxis(0.0, 0.0, zaxis); data3D.setMarkerRotatingCycle(8.0); data3D.setMarkerType(data[i][ivarMarkerType] == 1.0 ? markerTypes[0] : markerTypes[1]); } Canvas3DChart canvas = new Canvas3DChart(chart); canvas.setSize(375, 375); getContentPane().add(canvas, java.awt.BorderLayout.CENTER); jPanelLegend = new JPanel(new java.awt.GridBagLayout()); setupLegend(); getContentPane().add(jPanelLegend, java.awt.BorderLayout.WEST); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); pack(); ColormapLegend colormapLegend = new ColormapLegend(chart, colormap, minColor, maxColor); colormapLegend.setPosition(10, 10); colormapLegend.setTitle(meta.getColumnName(ivarMarkerColor+1)); canvas.render(); } private class AfifiAzenReader extends FlatFile { AfifiAzenReader(InputStream is) throws IOException { super(new BufferedReader(new InputStreamReader(is))); String line = readLine(); line = readLine(); line = readLine(); StringTokenizer st = new StringTokenizer(line, ","); for (int j = 0; st.hasMoreTokens(); j++) { setColumnName(j+1, st.nextToken().trim()); setColumnClass(j, Double.class); } } double[][] readData() throws IOException, java.sql.SQLException { double data[][] = new double[nObs][nVariables]; for (int i = 0; i < nObs; i++) { if (!next()) throw new IOException("Error in file"); for (int j = 0; j < nVariables; j++) { data[i][j] = getDouble(j+1); } } return data; } } static Summary getSummary(double data[][], int ivar) { Summary summary = new Summary(); for (int i = 0; i < nObs; i++) { summary.update(data[i][ivar]); } return summary; } private void setupLegend() throws SQLException { addLegendTitle("Marker Color:"); addLegendValue(ivarMarkerColor, 1.0); addLegendTitle("Marker Size:"); addLegendValue(ivarMarkerSize, 1.0); addLegendTitle("Marker Pulse (min/max):"); addLegendValue(ivarMarkerPulseMin, 0.0); addLegendValue(ivarMarkerPulseMax, 1.0); addLegendTitle("Rotation Axis:"); addLegendValue(ivarRotationAxis, 1.0); addLegendTitle("Marker Type:"); addLegendValue(ivarMarkerType, 1.0); } private void addLegendTitle(String title) { JLabel jLabel = new JLabel(title); java.awt.GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; jPanelLegend.add(jLabel, gridBagConstraints); } private void addLegendValue(int ivar, double weight) throws SQLException { JLabel jLabel = new JLabel(meta.getColumnName(ivar+1)); java.awt.GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.weighty = weight; jPanelLegend.add(jLabel, gridBagConstraints); jLabel.setForeground(Color.BLUE); } public static void main(String args[]) throws IOException, java.sql.SQLException { new DataEx3().setVisible(true); } }