Choropleth Maps

The package contains functions to plot Choropleth Maps using different classification methods.

All the examples on this page asummes that the Guerry dataset and the Plots.jl package is loaded.

using SpatialDependence
using SpatialDatasets
using Plots

guerry = sdataset("Guerry");

Choropleth maps can be made with plot function, with the first parameter being a vector of geometries, the second parameter the variable to classify, and the third parameter the classification method to use:

plot(guerry.geometry, guerry.Litercy, EqualIntervals())

It is also possible to pass a Table or a DataFrame as the first parameter and a symbol as the second parameter:

plot(guerry, :Litercy, EqualIntervals())

Graduated

Equal Intervals

Spatial observations are grouped into categories of the same length:

plot(guerry, :Litercy, EqualIntervals())
Example block output

It is possible to specify a different number of intervals:

plot(guerry, :Litercy, EqualIntervals(3))

Quantiles

Spatial observations are grouped according to quantiles:

plot(guerry, :Litercy, Quantiles())
Example block output

By default, spatial observations are categorized in quintiles (5 quantiles). It is possible to specify a different number of quantiles:

plot(guerry, :Litercy, Quantiles(4))

Natural Breaks (Jenks)

The Natural Breaks (Jenks) algorithm classify observations into groups with low heterogeneity within groups and high heterogeneity between groups:

plot(guerry, :Litercy, NaturalBreaks())
Example block output

Is it possible to specify a different number of groups:

plot(guerry, :Litercy, NaturalBreaks(7))

Custom Breaks

Users can specify the bins to generate custom breaks. The lower bound of the first class is set at the minimum value and the upper bound of the last class at the maximum value.

plot(guerry, :Litercy, CustomBreaks([20, 30, 60]))
Example block output

Statistical

Box Plot (Box map)

This method classify observations as in a box plot:

CategoryLowerUpper
1-$\infty$$Q_{25} - h * IQR$
2$Q_{25} - h * IQR$$Q_{25}$
3$Q_{25}$$Q_{50}$
4$Q_{50}$$Q_{75}$
5$Q_{75}$$Q_{75} + h * IQR$
6$Q_{75} + h * IQR$$\infty$

where $Q_{25}$, $Q_{50}$ and $Q_{75}$, are the first, second and third quartile respectively. $IQR$ is the interquartile range, and $h$ is the hinge.

plot(guerry, :Litercy, BoxPlot())
Example block output

By default, the hinge is set to $1.5$, but the user can choose a different value:

plot(guerry, :Litercy, BoxPlot(3.0))

Standard Deviation

In this method, observations are z-standardization and classified as standard deviations from the mean:

CategoryLowerUpper
1-$\infty$$-2$
2$-2$$-1$
3$-1$$0$
4$0$$1$
5$1$$2$
6$2$$\infty$
plot(guerry, :Litercy, StdMean())
Example block output

Percentiles

Observations are classified according to the following percentiles:

CategoryLowerUpper
1minimum$1\%$
2$1\%$$10\%$
3$10\%$$50\%$
4$50\%$$90\%$
5$90\%$$99\%$
6$99\%$maximum
plot(guerry, :Litercy, Percentiles())
Example block output

It is possible to specify different percentiles:

plot(guerry.geometry, guerry.Litercy, Percentiles([10, 30, 50, 70, 90]))

Unique Values

In a Unique Values map, each unique value is assigned to a different category.

plot(guerry, :Region, Unique())
Example block output

Co-location

Co-location maps are used to identify spatial observations where the categories of two or more variables match.

plot(guerry, [:Litercy, :Donatns], CoLocation(BoxPlot()))
Example block output

Customizing Maps

By default, the lower interval is open (value not included), and the upper interval is closed (value is included). It is possible to change this behavior by setting the lower and upper parameters to :open or :closed.

plot(guerry, :Litercy, Quantiles(), lower = :closed, upper = :open)
Example block output

Total counts are automatically added to the labels of the categories in the map. It is possible to suppress counts by setting the counts parameter to false.

plot(guerry, :Litercy, Quantiles(), counts = false)
Example block output

In graduated maps, the lower and upper bound are separated with a comma. It is possible to specify a different separator with the sep parameter:

plot(guerry, :Litercy, Quantiles(), sep = " -- ")
Example block output

It is possible to change the legend position with the legend parameter. Possible values are: :best, :topleft, :top, :topright, :right, :bottomright, :bottom, :bottomleft, :left. It also possible to place the legend outside the plot area with: :outertopleft, :outertop, :outertopright, :outerright, :outerbottomright, :outerbottom, :outerbottomleft. The legend can be removed by setting the parameter to false.

plot(guerry, :Litercy, Quantiles(), legend = :topleft)
Example block output

The legend's white background color can be removed by passing the argument background_color_legend = nothing and the black border with foreground_color_legend = nothing.

Color palette is set by default to :YlOrBr for graduated maps, reverse :RdBu for statistical maps, and :Paired for unique values maps. Users can change the palette with the palette parameter and reverse the colors by setting rev to true. A list of the color shcemes available in the Plots.jl package can be found here.

plot(guerry, :Litercy, Quantiles(), palette = :greens, rev = true)
Example block output

Classify without mapping

Users interested only in the classification and not in the choropleth map can use the functions mapclassify to obtain the classification of observations according to the criteria listed before.

mc = mapclassify(Quantiles(), guerry.Litercy);

It is possible to obtain the number of observations on each class with the counts function:

counts(mc)
5-element Vector{Int64}:
 18
 19
 15
 16
 17

The lower and upper bounds can be retrieved with the bounds function:

lbound, ubound = bounds(mc)
([12.0, 23.0, 31.0, 43.0, 54.400000000000006], [23.0, 31.0, 43.0, 54.400000000000006, 74.0])

With the maplabels function, it is possible to generate the labels of the classes:

labs = maplabels(mc)
5-element Vector{String}:
 "[12.0, 23.0] (18)"
 "(23.0, 31.0] (19)"
 "(31.0, 43.0] (15)"
 "(43.0, 54.4] (16)"
 "(54.4, 74.0] (17)"

We can obtain the class to which each observation is assigned with the assignments function:

assignments(mc)
85-element Vector{Int64}:
 3
 4
 1
 4
 5
 2
 5
 1
 5
 3
 ⋮
 1
 2
 1
 3
 2
 2
 1
 5
 4

For unique values and Co-location classifications, the levels of the classes can be obtained with the levels class:

mc = mapclassify(Unique(), guerry.Region)
levels(mc)
5-element Vector{String}:
 "E"
 "N"
 "C"
 "S"
 "W"