# scatterplot.py # ------------ # By MWC Contributors # Uses lots of helper functions in other modules to draw a scatter plot. from math import floor, ceil, log from turtle import * from superturtle.movement import no_delay import constants from generate_data import generate_data from ticks import get_tick_values from plotting import ( prepare_screen, draw_x_axis, draw_y_axis, draw_x_tick, draw_y_tick, draw_point, ) from superturtle.movement import no_delay import constants def flyto(x, y): penup() goto(x, y) pendown() from generate_data import generate_data from ticks import get_tick_values from plotting import ( prepare_screen, draw_point, ) from transform import ( bounds, scale, get_x_values, get_y_values ) def draw_x_axis(min_val, max_val): "Draws the x-axis of the scatter plot from min_val to max_val" penup flyto(0,0) goto(constants.PLOT_WIDTH,0) pendown() def get_tick_values(low, high): """Returns a list of values to use for ticks (labeled points along an axis). Includes the lowest value, a bunch of "nice" intermediate values, and the highest value. """ tick_interval = get_tick_interval(high - low) first_tick = ceil(low / tick_interval) * tick_interval return [low] + list(range(first_tick, high, tick_interval)) + [high] def get_tick_interval(span): """Returns a 'nice' interval for ticks across span. The interval is a power of ten (e.g. 1000, 100, 0.1) scaled so that there will be between 0 and 10 internal ticks. """ log_span = log(span, 10) return 10 ** floor(log_span) def draw_y_axis(min_val, max_val): "Draws the y-axis of the scatterplot from min_val to max_val" penup() flyto(0,0) goto(0,constants.PLOT_HEIGHT) pendown def draw_x_tick(position, label): "Draws a tick mark on the x-axis at the specified position" flyto(position, 0) goto(position, -constants.TICK_LENGTH) flyto(position, -constants.TICK_LENGTH - 10) write(label, align='center') def draw_y_tick(position, label): "Draws a tick mark on the y-axis at the specified position" flyto(0, position) goto(-constants.TICK_LENGTH, position) write(label, align='right') def get_tick_values(low, high): """Returns a list of values to use for ticks (labeled points along an axis). Includes the lowest value, a bunch of "nice" intermediate values, and the highest value. """ tick_interval = get_tick_interval(high - low) first_tick = ceil(low / tick_interval) * tick_interval return [low] + list(range(first_tick, high, tick_interval)) + [high] def draw_scatterplot(data, size=5, color="black"): "Draws a scatter plot, showing the data" prepare_screen() draw_axes(data) draw_points(data, size, color) def draw_axes(data): "Draws the scatter plot's axes." x_values = get_x_values(data) y_values = get_y_values(data) xmin, xmax = bounds(x_values) ymin, ymax = bounds(y_values) draw_x_axis(xmin, xmax) draw_y_axis(ymin, ymax) def draw_points(x,y, color="blue", size=5): "Draws the scatter plot's points." x_values = get_x_values(data) y_values = get_y_values(data) xmin, xmax = bounds(x_values) ymin, ymax = bounds(y_values) for point in data: x, y = point screen_x = scale(x, xmin, xmax, 0, constants.PLOT_WIDTH) screen_y = scale(y, ymin, ymax, 0, constants.PLOT_HEIGHT) draw_point(screen_x, screen_y, color, size) with no_delay(): data = generate_data(50, 10, 500, 5, 400, 1000) draw_scatterplot(data, size=5, color="blue") hideturtle() done()