// This program draws a scatter plot of exam midterm // scores and exam score predictions. import java.awt.*; import java.util.*; import java.io.*; public class Scatterplot { public static final int WIDTH = 2100; public static final int HEIGHT = 1100; public static final int GUTTER = 200; public static final int Y_AXIS = HEIGHT + GUTTER; public static final int X_AXIS = GUTTER; public static final int TICK_SIZE = 10; public static final Font LABEL_FONT = new Font("monospace", Font.BOLD, 24); public static void main(String[] args) throws FileNotFoundException { DrawingPanel panel = new DrawingPanel(WIDTH + 2 * GUTTER, HEIGHT + 2 * GUTTER); Graphics pen = panel.getGraphics(); drawScatterPlot(pen); } // Draws a scatter plot of exam scores vs predicted scores public static void drawScatterPlot(Graphics pen) throws FileNotFoundException { drawAxes(pen); drawXTicks(pen, 10, 10); drawYTicks(pen, 20, 5); drawPoints(pen); } // Draw all the points that are in the data file on the graph public static void drawPoints(Graphics pen) throws FileNotFoundException { File file = new File("18wi-mid-scores.txt"); Scanner input = new Scanner(file); // Scanner input = new Scanner(new File("18wi-mid-scores.txt")); while (input.hasNextLine()) { String line = input.nextLine(); Scanner lineScan = new Scanner(line); // if lineScan.hasNextInt() wouldn't be a bad check. // but we know that every line in the input file has // at least an actual score int actual = lineScan.nextInt(); if (lineScan.hasNextDouble()) { double prediction = lineScan.nextDouble(); drawMark(pen, actual, prediction); } else { System.out.println("Error, no prediction on line: " + line); } } } // Uses the given Graphics to draw a point at the given actual/predicted // location. Assumes max score of 100 for graphing public static void drawMark(Graphics pen, int actual, double predicted) { int max = 100; int size = 8; int centering = size / 2; pen.setColor(Color.RED); int xOffset = (int) Math.round( (1.0 * actual / max) * WIDTH - centering ); int yHeight = (int) Math.round( (predicted / max) * HEIGHT + centering ); pen.fillOval(X_AXIS + xOffset, Y_AXIS - yHeight, size, size); } // Use the given Graphics to draw (marks + 1) tick marks, each mark representing // a jump of stepSize units on the x axis. public static void drawXTicks(Graphics pen, int marks, int stepSize) { int textSetback = 70; int textHeight = 18; // somehow related to Font size :( pen.setFont(LABEL_FONT); for (int i = 0; i <= marks; i++) { String label = "" + i * stepSize; int yHeight = i * (HEIGHT / marks); int y = Y_AXIS - yHeight; pen.drawString(label, X_AXIS - textSetback, y + textHeight / 2); pen.drawLine(X_AXIS, y, X_AXIS - TICK_SIZE, y); } } // Use the given Graphics to draw (marks + 1) tick marks, each mark representing // a jump of stepSize units on the y axis. public static void drawYTicks(Graphics pen, int marks, int stepSize) { int textSetback = 50; int textCharWidth = 12; // somehow related to Font size :( pen.setFont(LABEL_FONT); for (int i = 0; i <= marks; i++) { String label = "" + i * stepSize; int xOffset = i * (WIDTH / marks); int x = X_AXIS + xOffset; int labelX = x - label.length() * textCharWidth / 2; pen.drawString(label, labelX, Y_AXIS + textSetback); pen.drawLine(x, Y_AXIS, x, Y_AXIS + TICK_SIZE); } } // Use the given Graphics to draw the axes on the graph public static void drawAxes(Graphics pen) { pen.setColor(Color.BLACK); pen.drawLine(X_AXIS, Y_AXIS, X_AXIS, GUTTER); pen.drawLine(X_AXIS, Y_AXIS, WIDTH + GUTTER, Y_AXIS); } }