Skip to content

Commit

Permalink
#86: Add functionality and docs for using GeoJSON with geo charts.
Browse files Browse the repository at this point in the history
  • Loading branch information
kMutagene committed Jun 22, 2021
1 parent 15ea8d4 commit a68db7d
Show file tree
Hide file tree
Showing 5 changed files with 268 additions and 57 deletions.
120 changes: 120 additions & 0 deletions docs/5_0_choropleth-map.fsx
Expand Up @@ -131,4 +131,124 @@ choroplethMap2

(***hide***)
choroplethMap2 |> GenericChart.toChartHTML
(***include-it-raw***)

(**
## Using GeoJSON
[GeoJSON](https://en.wikipedia.org/wiki/GeoJSON) is an open standard format designed for representing simple geographical features, along with their non-spatial attributes.
GeoJSON, or at least the type of GeoJSON accepted by plotly.js are `FeatureCollection`s. A feature has for example the `geometry` field, which defines e.g. the corrdinates of it (think for example the coordinates of a polygon on the map)
and the `properties` field, a key-value pair of properties of the feature.
If you want to use GeoJSON with Plotly.NET (or any plotly flavor really), you have to know the property of the feature you are mapping your data to. In the following example this is simply the `id` of a feature, but you can access any property by `property.key`.
Consider the following GeoJSON:
*)

// we are using the awesome FSharp.Data project here to perform a http request
#r "nuget: FSharp.Data"

open FSharp.Data
open Newtonsoft.Json

let geoJson =
Http.RequestString "https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json"
|> JsonConvert.DeserializeObject // the easiest way to use the GeoJSON object is deserializing the JSON string.

(**
it looks like this:
```JSON
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"GEO_ID": "0500000US01001",
"STATE": "01",
"COUNTY": "001",
"NAME": "Autauga",
"LSAD": "County",
"CENSUSAREA": 594.436
},
"geometry": {
"type": "Polygon",
"coordinates": [[[-86.496774, 32.344437], [-86.717897, 32.402814], [-86.814912, 32.340803], [-86.890581, 32.502974], [-86.917595, 32.664169], [-86.71339, 32.661732], [-86.714219, 32.705694], [-86.413116, 32.707386], [-86.411172, 32.409937], [-86.496774, 32.344437]]]
},
"id": "01001"
}, ... MANY more features.
```
It basically contains all US counties as polygons on the map. Note that the `id` property corresponds to the [**fips code**](https://en.wikipedia.org/wiki/FIPS_county_code).
To visualize some data using these counties as locations on a choropleth map, we need some exmaple data:
*)

// we use the awesome Deedle data frame library to parse and extract our location and z data
#r "nuget: Deedle"
open Deedle
open System.IO
open System.Text

let data =
let dataString = Http.RequestString "https://raw.githubusercontent.com/plotly/datasets/master/fips-unemp-16.csv"
let byteArray = Encoding.UTF8.GetBytes(dataString)
use stream = new MemoryStream(byteArray)
Frame.ReadCsv(stream,true,separators=",",schema="fips=string,unemp=float")


(**
The data looks like this:
*)


data.Print()

(*** include-output ***)

(**
As the data contains the fips code and associated unemployment data, we can use the fips codes as locations and the unemployment as z data:
*)

let locationsGeoJSON: string [] =
data
|> Frame.getCol "fips"
|> Series.values
|> Array.ofSeq

let zGeoJSON: int [] =
data
|> Frame.getCol "unemp"
|> Series.values
|> Array.ofSeq


(**
And finally put together the chart using GeoJSON:
*)

let choroplethGeoJSON =
Chart.ChoroplethMap(
locations = locationsGeoJSON,
z = zGeoJSON,
Locationmode=StyleParam.LocationFormat.GeoJson_Id,
GeoJson = geoJson,
FeatureIdKey="id"
)
|> Chart.withMap(
Geo.init(
Scope=StyleParam.GeoScope.Usa
)
)
|> Chart.withSize (800.,800.)

(*** condition: ipynb ***)
#if IPYNB
choroplethGeoJSON
#endif // IPYNB

(***hide***)
choroplethGeoJSON |> GenericChart.toChartHTML
(***include-it-raw***)
130 changes: 74 additions & 56 deletions src/Plotly.NET/Chart.fs
Expand Up @@ -616,7 +616,6 @@ type Chart =
Chart.Range(x, y, upper, lower, ?Name=Name,?ShowMarkers=ShowMarkers,?Showlegend=Showlegend,?Color=Color,?RangeColor=RangeColor,?Labels=Labels,?TextPosition=TextPosition,?TextFont=TextFont)



/// Displays a range of data by plotting two Y values per data point, with each Y value being drawn as a line
static member Range(x, y, upper, lower,mode,
[<Optional;DefaultParameterValue(null)>] ?Name,
Expand Down Expand Up @@ -1463,11 +1462,13 @@ type Chart =
[<Optional;DefaultParameterValue(null)>] ?Colorscale,
[<Optional;DefaultParameterValue(null)>] ?Colorbar,
[<Optional;DefaultParameterValue(null)>] ?Marker,
[<Optional;DefaultParameterValue(null)>] ?GeoJson,
[<Optional;DefaultParameterValue(null)>] ?FeatureIdKey: string,
[<Optional;DefaultParameterValue(null)>] ?Zmin,
[<Optional;DefaultParameterValue(null)>] ?Zmax) =
Trace.initChoroplethMap (
TraceStyle.ChoroplethMap (Locations=locations,Z=z,?Text=Text,?Locationmode=Locationmode,?Autocolorscale=Autocolorscale,
?Colorscale=Colorscale,?Colorbar=Colorbar,?Marker=Marker,?Zmin=Zmin,?Zmax=Zmax)
?Colorscale=Colorscale,?Colorbar=Colorbar,?Marker=Marker,?Zmin=Zmin,?Zmax=Zmax,?GeoJson=GeoJson,?FeatureIdKey=FeatureIdKey)
)
|> GenericChart.ofTraceObject

Expand Down Expand Up @@ -2223,20 +2224,22 @@ type Chart =
[<Optional;DefaultParameterValue(null)>] ?Dash ,
[<Optional;DefaultParameterValue(null)>] ?Width : float ,
[<Optional;DefaultParameterValue(null)>] ?GeoJson ,
[<Optional;DefaultParameterValue(null)>] ?FeatureIdKey: string ,
[<Optional;DefaultParameterValue(null)>] ?Connectgaps : bool ,
[<Optional;DefaultParameterValue(null)>] ?Fill : StyleParam.Fill ,
[<Optional;DefaultParameterValue(null)>] ?Fillcolor
) =

Trace.initScatterGeo(
TraceStyle.ScatterGeo(
mode = mode ,
Longitudes = longitudes ,
Latitudes = latitudes ,
?GeoJson = GeoJson ,
?Connectgaps= Connectgaps ,
?Fill = Fill ,
?Fillcolor = Fillcolor
mode = mode ,
Longitudes = longitudes ,
Latitudes = latitudes ,
?GeoJson = GeoJson ,
?FeatureIdKey = FeatureIdKey ,
?Connectgaps = Connectgaps ,
?Fill = Fill ,
?Fillcolor = Fillcolor
)
)
|> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity)
Expand Down Expand Up @@ -2294,6 +2297,7 @@ type Chart =
[<Optional;DefaultParameterValue(null)>] ?Dash ,
[<Optional;DefaultParameterValue(null)>] ?Width : float ,
[<Optional;DefaultParameterValue(null)>] ?GeoJson ,
[<Optional;DefaultParameterValue(null)>] ?FeatureIdKey: string ,
[<Optional;DefaultParameterValue(null)>] ?Connectgaps : bool ,
[<Optional;DefaultParameterValue(null)>] ?Fill : StyleParam.Fill ,
[<Optional;DefaultParameterValue(null)>] ?Fillcolor
Expand All @@ -2302,13 +2306,14 @@ type Chart =

Trace.initScatterGeo(
TraceStyle.ScatterGeo(
mode = mode ,
Longitudes = longitudes ,
Latitudes = latitudes ,
?GeoJson = GeoJson ,
?Connectgaps= Connectgaps ,
?Fill = Fill ,
?Fillcolor = Fillcolor
mode = mode ,
Longitudes = longitudes ,
Latitudes = latitudes ,
?GeoJson = GeoJson ,
?FeatureIdKey = FeatureIdKey ,
?Connectgaps = Connectgaps ,
?Fill = Fill ,
?Fillcolor = Fillcolor
)
)
|> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity)
Expand Down Expand Up @@ -2365,19 +2370,21 @@ type Chart =
[<Optional;DefaultParameterValue(null)>] ?Dash ,
[<Optional;DefaultParameterValue(null)>] ?Width : float ,
[<Optional;DefaultParameterValue(null)>] ?GeoJson ,
[<Optional;DefaultParameterValue(null)>] ?FeatureIdKey: string ,
[<Optional;DefaultParameterValue(null)>] ?Connectgaps : bool ,
[<Optional;DefaultParameterValue(null)>] ?Fill : StyleParam.Fill ,
[<Optional;DefaultParameterValue(null)>] ?Fillcolor
) =

Trace.initScatterGeo(
TraceStyle.ScatterGeo(
mode = mode ,
?Locations = locations ,
?GeoJson = GeoJson ,
?Connectgaps= Connectgaps ,
?Fill = Fill ,
?Fillcolor = Fillcolor
mode = mode ,
?Locations = locations ,
?GeoJson = GeoJson ,
?FeatureIdKey = FeatureIdKey ,
?Connectgaps = Connectgaps ,
?Fill = Fill ,
?Fillcolor = Fillcolor
)
)
|> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity)
Expand Down Expand Up @@ -2427,6 +2434,7 @@ type Chart =
[<Optional;DefaultParameterValue(null)>] ?TextPosition ,
[<Optional;DefaultParameterValue(null)>] ?TextFont ,
[<Optional;DefaultParameterValue(null)>] ?GeoJson ,
[<Optional;DefaultParameterValue(null)>] ?FeatureIdKey: string ,
[<Optional;DefaultParameterValue(null)>] ?Connectgaps : bool ,
[<Optional;DefaultParameterValue(null)>] ?Fill : StyleParam.Fill ,
[<Optional;DefaultParameterValue(null)>] ?Fillcolor
Expand All @@ -2436,13 +2444,14 @@ type Chart =

Trace.initScatterGeo(
TraceStyle.ScatterGeo(
mode = changeMode StyleParam.Mode.Markers ,
Longitudes = longitudes ,
Latitudes = latitudes ,
?GeoJson = GeoJson ,
?Connectgaps= Connectgaps ,
?Fill = Fill ,
?Fillcolor = Fillcolor
mode = changeMode StyleParam.Mode.Markers ,
Longitudes = longitudes ,
Latitudes = latitudes ,
?GeoJson = GeoJson ,
?FeatureIdKey = FeatureIdKey ,
?Connectgaps = Connectgaps ,
?Fill = Fill ,
?Fillcolor = Fillcolor
)
)
|> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity)
Expand Down Expand Up @@ -2489,6 +2498,7 @@ type Chart =
[<Optional;DefaultParameterValue(null)>] ?TextPosition ,
[<Optional;DefaultParameterValue(null)>] ?TextFont ,
[<Optional;DefaultParameterValue(null)>] ?GeoJson ,
[<Optional;DefaultParameterValue(null)>] ?FeatureIdKey: string ,
[<Optional;DefaultParameterValue(null)>] ?Connectgaps : bool ,
[<Optional;DefaultParameterValue(null)>] ?Fill : StyleParam.Fill ,
[<Optional;DefaultParameterValue(null)>] ?Fillcolor
Expand All @@ -2499,13 +2509,14 @@ type Chart =

Trace.initScatterGeo(
TraceStyle.ScatterGeo(
mode = changeMode StyleParam.Mode.Markers ,
Longitudes = longitudes ,
Latitudes = latitudes ,
?GeoJson = GeoJson ,
?Connectgaps= Connectgaps ,
?Fill = Fill ,
?Fillcolor = Fillcolor
mode = changeMode StyleParam.Mode.Markers ,
Longitudes = longitudes ,
Latitudes = latitudes ,
?GeoJson = GeoJson ,
?FeatureIdKey = FeatureIdKey ,
?Connectgaps = Connectgaps ,
?Fill = Fill ,
?Fillcolor = Fillcolor
)
)
|> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity)
Expand Down Expand Up @@ -2552,6 +2563,7 @@ type Chart =
[<Optional;DefaultParameterValue(null)>] ?TextPosition ,
[<Optional;DefaultParameterValue(null)>] ?TextFont ,
[<Optional;DefaultParameterValue(null)>] ?GeoJson ,
[<Optional;DefaultParameterValue(null)>] ?FeatureIdKey: string ,
[<Optional;DefaultParameterValue(null)>] ?Connectgaps : bool ,
[<Optional;DefaultParameterValue(null)>] ?Fill : StyleParam.Fill ,
[<Optional;DefaultParameterValue(null)>] ?Fillcolor
Expand Down Expand Up @@ -2624,6 +2636,7 @@ type Chart =
[<Optional;DefaultParameterValue(null)>] ?TextPosition ,
[<Optional;DefaultParameterValue(null)>] ?TextFont ,
[<Optional;DefaultParameterValue(null)>] ?GeoJson ,
[<Optional;DefaultParameterValue(null)>] ?FeatureIdKey: string ,
[<Optional;DefaultParameterValue(null)>] ?Connectgaps : bool ,
[<Optional;DefaultParameterValue(null)>] ?Fill : StyleParam.Fill ,
[<Optional;DefaultParameterValue(null)>] ?Fillcolor
Expand All @@ -2639,13 +2652,14 @@ type Chart =

Trace.initScatterGeo(
TraceStyle.ScatterGeo(
mode = changeMode StyleParam.Mode.Lines,
Longitudes = longitudes ,
Latitudes = latitudes ,
?GeoJson = GeoJson ,
?Connectgaps= Connectgaps ,
?Fill = Fill ,
?Fillcolor = Fillcolor
mode = changeMode StyleParam.Mode.Lines,
Longitudes = longitudes ,
Latitudes = latitudes ,
?GeoJson = GeoJson ,
?FeatureIdKey = FeatureIdKey ,
?Connectgaps = Connectgaps ,
?Fill = Fill ,
?Fillcolor = Fillcolor
)
)
|> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity)
Expand Down Expand Up @@ -2697,6 +2711,7 @@ type Chart =
[<Optional;DefaultParameterValue(null)>] ?TextPosition ,
[<Optional;DefaultParameterValue(null)>] ?TextFont ,
[<Optional;DefaultParameterValue(null)>] ?GeoJson ,
[<Optional;DefaultParameterValue(null)>] ?FeatureIdKey: string ,
[<Optional;DefaultParameterValue(null)>] ?Connectgaps : bool ,
[<Optional;DefaultParameterValue(null)>] ?Fill : StyleParam.Fill ,
[<Optional;DefaultParameterValue(null)>] ?Fillcolor
Expand All @@ -2713,13 +2728,14 @@ type Chart =

Trace.initScatterGeo(
TraceStyle.ScatterGeo(
mode = changeMode StyleParam.Mode.Lines,
Longitudes = longitudes ,
Latitudes = latitudes ,
?GeoJson = GeoJson ,
?Connectgaps= Connectgaps ,
?Fill = Fill ,
?Fillcolor = Fillcolor
mode = changeMode StyleParam.Mode.Lines,
Longitudes = longitudes ,
Latitudes = latitudes ,
?GeoJson = GeoJson ,
?FeatureIdKey = FeatureIdKey ,
?Connectgaps = Connectgaps ,
?Fill = Fill ,
?Fillcolor = Fillcolor
)
)
|> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity)
Expand Down Expand Up @@ -2771,6 +2787,7 @@ type Chart =
[<Optional;DefaultParameterValue(null)>] ?TextPosition ,
[<Optional;DefaultParameterValue(null)>] ?TextFont ,
[<Optional;DefaultParameterValue(null)>] ?GeoJson ,
[<Optional;DefaultParameterValue(null)>] ?FeatureIdKey: string ,
[<Optional;DefaultParameterValue(null)>] ?Connectgaps : bool ,
[<Optional;DefaultParameterValue(null)>] ?Fill : StyleParam.Fill ,
[<Optional;DefaultParameterValue(null)>] ?Fillcolor
Expand All @@ -2786,12 +2803,13 @@ type Chart =

Trace.initScatterGeo(
TraceStyle.ScatterGeo(
mode = changeMode StyleParam.Mode.Lines,
Locations = locations ,
?GeoJson = GeoJson ,
?Connectgaps= Connectgaps ,
?Fill = Fill ,
?Fillcolor = Fillcolor
mode = changeMode StyleParam.Mode.Lines,
Locations = locations ,
?GeoJson = GeoJson ,
?FeatureIdKey = FeatureIdKey ,
?Connectgaps = Connectgaps ,
?Fill = Fill ,
?Fillcolor = Fillcolor
)
)
|> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity)
Expand Down

0 comments on commit a68db7d

Please sign in to comment.