module-8-scatterplot-blank 2025-04-13, 10:00 PM
Mapping Crime in Vancouver
Let's just have some plotting fun!
This is loosely an HtDAP design, but we've skipped the planning stages to keep it short!
We're also working from the Module 7 VPD location project for fun :)
So, edit and refactor this into something to map crime! (We've already updated the data
definitions and read function, but not main or analyze !)
In [6]:
from cs103 import *
from typing import NamedTuple, List
from enum import Enum
import csv
import [Link] as pyplot
##################
# Data Definitions
CrimeData = NamedTuple('CrimeData', [('x', float),
('y', float)])
# interp. data about a single crime in Vancouver with its x and y location.
# (Locations are in metres offset from a somewhat arbitrary point on the surface of
# the earth. (Caution: locations of (0, 0) are sometimes placeholders
# or intentionally inaccurate reports. Fortunately, that doesn't occur in the
# subset of the data we're looking at.)
CD1 = CrimeData(0, 0)
CD2 = CrimeData(-3.5, 2.0)
CD3 = CrimeData(490258.683, 5458154.503) # sample location actually pulled from ou
# template based on compound (2 fields)
@typecheck
def fn_for_crime_data(cd: CrimeData) -> ...:
return ...(cd.x,
cd.y)
CrimeDataList = List[CrimeData]
# interp. a list of crime data
LOCD0 = []
LOCD1 = [CD1, CD2]
# template based on arbitrary-sized data and reference rule
@typecheck
def fn_for_cdl(cdl: CrimeDataList) -> ...:
# description of accumulator
acc = ... # type: ...
about:srcdoc Page 1 of 9
module-8-scatterplot-blank 2025-04-13, 10:00 PM
for cd in cdl:
acc = ...(fn_for_crime_data(cd), acc)
return ...(acc)
FloatList = List[float]
# interp. a list of floats
LOF0 = []
LOF1 = [0, -3.5]
# template based on arbitrary-sized data
@typecheck
def fn_for_float_list(fl: FloatList) -> ...:
# description of accumulator
acc = ... # type: ...
for f in fl:
acc = ...(f, acc)
return ...(acc)
about:srcdoc Page 2 of 9
module-8-scatterplot-blank 2025-04-13, 10:00 PM
In [7]:
@typecheck
def read(filename: str) -> CrimeDataList:
"""
reads information from the specified file and returns a list of crime data
the file must be in the VPD crime format, and the x and y entries must be valid
floats.
"""
# Note: in future, we might want to skip (0, 0) entries, but we won't now.
#return [] #stub
# Template from HtDAP
# locd contains the result so far
locd = [] # type: List[CrimeData]
with open(filename) as csvfile:
reader = [Link](csvfile)
next(reader) # skip header line
for row in reader:
cd = CrimeData(parse_float(row[8]), parse_float(row[9]))
[Link](cd)
return locd
start_testing()
expect(read("testfile_empty.csv"), [])
expect(read("testfile_small.csv"), [CrimeData(0, 0),
CrimeData(-3.5, 2.0)])
summary()
2 of 2 tests passed
about:srcdoc Page 3 of 9
module-8-scatterplot-blank 2025-04-13, 10:00 PM
Scatterplot solution from the worksheet
Our "template" in the viz module is just to copy-and-paste from a sample of the kind of plot
we want. That's not so unrealistic as a starting point as long as we understand what we're
using!
Here's the scatterplot worked example body as a starting point for our template:
@typecheck
def show_scatterplot(ages: IntList, salaries: IntList, counts:
IntList) -> None:
"""
display a scatterplot of salaries vs. ages. salaries are given in
1000s
Assumes that the lengths of ages, salaries, and counts are all
equal
"""
#return None #stub
# Template based on visualization
areas = convert_counts_to_areas(counts)
# set the labels for the axes
[Link]('Age')
[Link]('Salary (in 1000s)')
[Link]('Salaries by age')
# range for the axes
# [x-min, x-max, y-min, y-max]
[Link]([0,65,0,105])
# create the scatterplot, with markers that are red (c='r') and
triangular (marker='^')
[Link](ages,salaries,marker='^', c='r', s=areas)
# show the plot
[Link]()
return None
In [8]:
@typecheck
def main(filename: str) -> ...:
"""
Reads the file from given filename, analyzes the data,
returns the result
about:srcdoc Page 4 of 9
module-8-scatterplot-blank 2025-04-13, 10:00 PM
"""
# Template from HtDAP, based on composition
return analyze(read(filename))
@typecheck
# You will often want to rename this function!
def analyze(loc: List[Consumed]) -> Produced:
"""
...
"""
return ...
# Here are some helper functions which we have provided for you
# as they are not terribly interesting.
@typecheck
def get_x_locations(cdl:CrimeDataList) -> FloatList:
"""
return the x locations from cdl
"""
#return [] #stub
# template from CrimeDataList
# acc is the result so far
acc = [] # type: FloatList
for cd in cdl:
[Link](cd.x)
return acc
@typecheck
def get_y_locations(cdl: CrimeDataList) -> FloatList:
"""
return the y locations from cdl
"""
#return [] #stub
# template from CrimeDataList
# acc is the result so far
acc = [] # type: List[float]
for cd in cdl:
[Link](cd.y)
return acc
###########################
# Tests for main
###########################
start_testing()
expect(..., ...)
about:srcdoc Page 5 of 9
module-8-scatterplot-blank 2025-04-13, 10:00 PM
summary()
###########################
# Tests for analyze
###########################
start_testing()
expect(..., ...)
summary()
###########################
# Tests for get_x_locations
###########################
start_testing()
expect(get_x_locations([]), [])
expect(get_x_locations([CrimeData(0, 0), CrimeData(-3.5, 2.0)]), [0, -3.5])
summary()
###########################
# Tests for get_y_locations
###########################
start_testing()
expect(get_y_locations([]), [])
expect(get_y_locations([CrimeData(0, 0), CrimeData(-3.5, 2.0)]), [0, 2.0])
summary()
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-8-779e71134882> in <module>
10 @typecheck
11 # You will often want to rename this function!
---> 12 def analyze(loc: List[Consumed]) -> Produced:
13 """
14 ...
NameError: name 'Consumed' is not defined
In [9]:
# Use this to determine what arguments are REQUIRED and
# what other customization options are possible
help([Link])
Help on function scatter in module [Link]:
scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vm
ax=None, alpha=None, linewidths=None, verts=<deprecated parameter>, edgecolors
=None, *, plotnonfinite=False, data=None, **kwargs)
A scatter plot of *y* vs. *x* with varying marker size and/or color.
about:srcdoc Page 6 of 9
module-8-scatterplot-blank 2025-04-13, 10:00 PM
Parameters
----------
x, y : float or array-like, shape (n, )
The data positions.
s : float or array-like, shape (n, ), optional
The marker size in points**2.
Default is ``rcParams['[Link]'] ** 2``.
c : array-like or list of colors or color, optional
The marker colors. Possible values:
- A scalar or sequence of n numbers to be mapped to colors using
*cmap* and *norm*.
- A 2-D array in which the rows are RGB or RGBA.
- A sequence of colors of length n.
- A single color format string.
Note that *c* should not be a single numeric RGB or RGBA sequence
because that is indistinguishable from an array of values to be
colormapped. If you want to specify the same RGB or RGBA value for
all points, use a 2-D array with a single row. Otherwise, value-
matching will have precedence in case of a size matching with *x*
and *y*.
If you wish to specify a single color for all points
prefer the *color* keyword argument.
Defaults to `None`. In that case the marker color is determined
by the value of *color*, *facecolor* or *facecolors*. In case
those are not specified or `None`, the marker color is determined
by the next color of the ``Axes``' current "shape and fill" color
cycle. This cycle defaults to :rc:`axes.prop_cycle`.
marker : `~.[Link]`, default: :rc:`[Link]`
The marker style. *marker* can be either an instance of the class
or the text shorthand for a particular marker.
See :mod:`[Link]` for more information about marker
styles.
cmap : str or `~[Link]`, default: :rc:`[Link]`
A `.Colormap` instance or registered colormap name. *cmap* is only
used if *c* is an array of floats.
norm : `~[Link]`, default: None
If *c* is an array of floats, *norm* is used to scale the color
data, *c*, in the range 0 to 1, in order to map into the colormap
*cmap*.
If *None*, use the default `.[Link]`.
vmin, vmax : float, default: None
*vmin* and *vmax* are used in conjunction with the default norm to
map the color array *c* to the colormap *cmap*. If None, the
respective min and max of the color array is used.
It is deprecated to use *vmin*/*vmax* when *norm* is given.
about:srcdoc Page 7 of 9
module-8-scatterplot-blank 2025-04-13, 10:00 PM
alpha : float, default: None
The alpha blending value, between 0 (transparent) and 1 (opaque).
linewidths : float or array-like, default: :rc:`[Link]`
The linewidth of the marker edges. Note: The default *edgecolors*
is 'face'. You may want to change this as well.
edgecolors : {'face', 'none', *None*} or color or sequence of color, defau
lt: :rc:`[Link]`
The edge color of the marker. Possible values:
- 'face': The edge color will always be the same as the face color.
- 'none': No patch boundary will be drawn.
- A color or sequence of colors.
For non-filled markers, the *edgecolors* kwarg is ignored and
forced to 'face' internally.
plotnonfinite : bool, default: False
Set to plot points with nonfinite *c*, in conjunction with
`~[Link].set_bad`.
Returns
-------
`~[Link]`
Other Parameters
----------------
**kwargs : `~[Link]` properties
See Also
--------
plot : To plot scatter plots when markers are identical in size and
color.
Notes
-----
* The `.plot` function will be faster for scatterplots where markers
don't vary in size or color.
* Any or all of *x*, *y*, *s*, and *c* may be masked arrays, in which
case all masks will be combined and only unmasked points will be
plotted.
* Fundamentally, scatter works with 1-D arrays; *x*, *y*, *s*, and *c*
may be input as N-D arrays, but within scatter they will be
flattened. The exception is *c*, which will be flattened only if its
size matches the size of *x* and *y*.
.. note::
In addition to the above described arguments, this function can take
a *data* keyword argument. If such a *data* argument is given,
the following arguments can also be string ``s``, which is
interpreted as ``data[s]`` (unless this raises an exception):
*x*, *y*, *s*, *linewidths*, *edgecolors*, *c*, *facecolor*, *facecolo
rs*, *color*.
about:srcdoc Page 8 of 9
module-8-scatterplot-blank 2025-04-13, 10:00 PM
Objects passed as **data** must support item access (``data[s]``) and
membership test (``s in data``).
In [10]:
# Here is our overall average location!
# Compare this to the map found at [Link]
main("crimedata_subset_bne_theft_of_bike_veh_2018.csv")
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-10-f7c9ccd0991c> in <module>
2 # Compare this to the map found at [Link]
ancouver,+BC
3
----> 4 main("crimedata_subset_bne_theft_of_bike_veh_2018.csv")
/opt/conda/lib/python3.8/site-packages/cs103/typecheck/[Link] in wrappe
r(*args)
133 raise TypeError("The function \x1b[34m%s\x1b[0m is mis
sing a type for the parameter %s." % (fn.__name__, name))
134
--> 135 retval = fn(*args)
136 if 'return' in types:
137 subtype("the returned value", retval, types['return'], fn,
True)
<ipython-input-8-779e71134882> in main(filename)
6 """
7 # Template from HtDAP, based on composition
----> 8 return analyze(read(filename))
9
10 @typecheck
NameError: name 'analyze' is not defined
In [ ]:
In [ ]:
about:srcdoc Page 9 of 9