diff --git a/Plotly.NET.sln b/Plotly.NET.sln index 25549edcc..da7661dcc 100644 --- a/Plotly.NET.sln +++ b/Plotly.NET.sln @@ -74,15 +74,21 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "content", "content", "{60FB docs\4_3_contour-plots.fsx = docs\4_3_contour-plots.fsx docs\4_4_2d-histograms.fsx = docs\4_4_2d-histograms.fsx docs\4_5_splom.fsx = docs\4_5_splom.fsx - docs\5_0_choropleth-map.fsx = docs\5_0_choropleth-map.fsx - docs\6_0_candlestick.fsx = docs\6_0_candlestick.fsx - docs\6_1_funnel.fsx = docs\6_1_funnel.fsx - docs\6_2_funnel_area.fsx = docs\6_2_funnel_area.fsx - docs\7_0_polar-charts.fsx = docs\7_0_polar-charts.fsx - docs\7_1_windrose-charts.fsx = docs\7_1_windrose-charts.fsx - docs\8_0_parallel-categories.fsx = docs\8_0_parallel-categories.fsx - docs\8_1_parallel-coords.fsx = docs\8_1_parallel-coords.fsx - docs\8_2_sankey.fsx = docs\8_2_sankey.fsx + docs\5_0_geo-vs-mapbox.fsx = docs\5_0_geo-vs-mapbox.fsx + docs\5_1_geo-plots.fsx = docs\5_1_geo-plots.fsx + docs\5_2_choropleth-map.fsx = docs\5_2_choropleth-map.fsx + docs\6_0_geo-vs-mapbox.fsx = docs\6_0_geo-vs-mapbox.fsx + docs\6_1_mapbox-plots.fsx = docs\6_1_mapbox-plots.fsx + docs\6_2_choropleth-mapbox.fsx = docs\6_2_choropleth-mapbox.fsx + docs\6_3_density-mapbox.fsx = docs\6_3_density-mapbox.fsx + docs\7_0_candlestick.fsx = docs\7_0_candlestick.fsx + docs\7_1_funnel.fsx = docs\7_1_funnel.fsx + docs\7_2_funnel_area.fsx = docs\7_2_funnel_area.fsx + docs\8_0_polar-charts.fsx = docs\8_0_polar-charts.fsx + docs\8_1_windrose-charts.fsx = docs\8_1_windrose-charts.fsx + docs\9_0_parallel-categories.fsx = docs\9_0_parallel-categories.fsx + docs\9_1_parallel-coords.fsx = docs\9_1_parallel-coords.fsx + docs\9_2_sankey.fsx = docs\9_2_sankey.fsx docs\_template.html = docs\_template.html docs\_template.ipynb = docs\_template.ipynb docs\Dockerfile = docs\Dockerfile diff --git a/docs/5_0_geo-vs-mapbox.fsx b/docs/5_0_geo-vs-mapbox.fsx new file mode 100644 index 000000000..87ca09947 --- /dev/null +++ b/docs/5_0_geo-vs-mapbox.fsx @@ -0,0 +1,131 @@ +(** +--- +title: Geo vs. Mapbox +category: Geo map charts +categoryindex: 6 +index: 1 +--- +*) + +(*** hide ***) + +(*** condition: prepare ***) +#r "nuget: Newtonsoft.JSON, 12.0.3" +#r "../bin/Plotly.NET/netstandard2.0/Plotly.NET.dll" + +(*** condition: ipynb ***) +#if IPYNB +#r "nuget: Plotly.NET, {{fsdocs-package-version}}" +#r "nuget: Plotly.NET.Interactive, {{fsdocs-package-version}}" +#endif // IPYNB + +(** +# Mapbox Maps vs Geo Maps + +[![Binder]({{root}}img/badge-binder.svg)](https://mybinder.org/v2/gh/plotly/Plotly.NET/gh-pages?filepath={{fsdocs-source-basename}}.ipynb)  +[![Script]({{root}}img/badge-script.svg)]({{root}}{{fsdocs-source-basename}}.fsx)  +[![Notebook]({{root}}img/badge-notebook.svg)]({{root}}{{fsdocs-source-basename}}.ipynb) + +*Summary:* This introduction shows the differences between Geo and Mapbox based geographical charts. + +Plotly and therefore Plotly.NET supports two different kinds of maps: + +- **Mapbox maps** are tile-based maps. If your figure is created with a `Chart.*Mapbox` function or otherwise contains one or more traces of type `scattermapbox`, + `choroplethmapbox` or `densitymapbox`, the layout.mapbox object in your figure contains configuration information for the map itself. + +- **Geo maps** are outline-based maps. If your figure is created with a `Chart.ScatterGeo, `Chart.PointGeo`, `Chart.LineGeo` or `Chart.Choropleth` function or + otherwise contains one or more traces of type `scattergeo` or `choropleth`, the layout.geo object in your figure contains configuration information for the map itself. + +_This page documents Geo outline-based maps, and the [Mapbox Layers documentation]({{root}}/6_0_geo-vs-mapbox.html) describes how to configure Mapbox tile-based maps._ + +## Physical Base Maps + +Plotly Geo maps have a built-in base map layer composed of "physical" and "cultural" (i.e. administrative border) data from the Natural Earth Dataset. +Various lines and area fills can be shown or hidden, and their color and line-widths specified. +In the default plotly template, a map frame and physical features such as a coastal outline and filled land areas are shown, at a small-scale 1:110m resolution: + +*) + +open Plotly.NET + +let baseMapOnly = + Chart.PointGeo([]) // deliberately empty chart to show the base map only + |> Chart.withMarginSize(0,0,0,0) + +(*** condition: ipynb ***) +#if IPYNB +baseLayerOnly +#endif // IPYNB + +(***hide***) +baseMapOnly |> GenericChart.toChartHTML +(***include-it-raw***) + +(** +To control the features of the map, a `Geo` object is used that can be associtaed with a given chart using the `Chart.WithGeo` function. +Here is a map with all physical features enabled and styled, at a larger-scale 1:50m resolution: +*) + +let myGeo = + Geo.init( + Resolution=StyleParam.GeoResolution.R50, + ShowCoastLines=true, + CoastLineColor="RebeccaPurple", + ShowLand=true, + LandColor="LightGreen", + ShowOcean=true, + OceanColor="LightBlue", + ShowLakes=true, + LakeColor="Blue", + ShowRivers=true, + RiverColor="Blue" + ) + +let moreFeaturesBaseMap = + Chart.PointGeo([]) + |> Chart.withMap myGeo + |> Chart.withMarginSize(0,0,0,0) + +(*** condition: ipynb ***) +#if IPYNB +moreFeaturesBaseMap +#endif // IPYNB + +(***hide***) +moreFeaturesBaseMap |> GenericChart.toChartHTML +(***include-it-raw***) + +(** +## Cultural Base Maps + +In addition to physical base map features, a "cultural" base map is included which is composed of country borders and selected sub-country borders such as states. + +_Note and disclaimer: cultural features are by definition subject to change, debate and dispute. Plotly includes data from Natural Earth "as-is" and defers to the Natural Earth policy regarding disputed borders which read:_ + +> Natural Earth Vector draws boundaries of countries according to defacto status. We show who actually controls the situation on the ground. + +Here is a map with only cultural features enabled and styled, at a 1:50m resolution, which includes only country boundaries. See below for country sub-unit cultural base map features: +*) + +let countryGeo = + Geo.init( + Visible=false, + Resolution=StyleParam.GeoResolution.R50, + ShowCountries=true, + CountryColor="RebeccaPurple" + ) + + +let countryBaseMap = + Chart.PointGeo([]) + |> Chart.withMap countryGeo + |> Chart.withMarginSize(0,0,0,0) + +(*** condition: ipynb ***) +#if IPYNB +countryBaseMap +#endif // IPYNB + +(***hide***) +countryBaseMap |> GenericChart.toChartHTML +(***include-it-raw***) diff --git a/docs/5_1_geo-plots.fsx b/docs/5_1_geo-plots.fsx new file mode 100644 index 000000000..d068a990a --- /dev/null +++ b/docs/5_1_geo-plots.fsx @@ -0,0 +1,127 @@ +(** +--- +title: Scatter and line plots on Geo maps +category: Geo map charts +categoryindex: 6 +index: 2 +--- +*) + +(*** hide ***) + +(*** condition: prepare ***) +#r "nuget: Newtonsoft.JSON, 12.0.3" +#r "../bin/Plotly.NET/netstandard2.0/Plotly.NET.dll" + +(*** condition: ipynb ***) +#if IPYNB +#r "nuget: Plotly.NET, {{fsdocs-package-version}}" +#r "nuget: Plotly.NET.Interactive, {{fsdocs-package-version}}" +#endif // IPYNB + +(** +# Scatter and line plots on Geo maps + +[![Binder]({{root}}img/badge-binder.svg)](https://mybinder.org/v2/gh/plotly/Plotly.NET/gh-pages?filepath={{fsdocs-source-basename}}.ipynb)  +[![Script]({{root}}img/badge-script.svg)]({{root}}{{fsdocs-source-basename}}.fsx)  +[![Notebook]({{root}}img/badge-notebook.svg)]({{root}}{{fsdocs-source-basename}}.ipynb) + +*Summary:* This example shows how to create Point and Line charts on geo maps in F#. + +let's first create some data for the purpose of creating example charts: +*) +open Plotly.NET + +let cityNames = [ + "Montreal"; "Toronto"; "Vancouver"; "Calgary"; "Edmonton"; + "Ottawa"; "Halifax"; "Victoria"; "Winnepeg"; "Regina" +] + +let lon = [ + -73.57; -79.24; -123.06; -114.1; -113.28; + -75.43; -63.57; -123.21; -97.13; -104.6 +] +let lat = [ + 45.5; 43.4; 49.13; 51.1; 53.34; 45.24; + 44.64; 48.25; 49.89; 50.45 +] + +(** +The simplest type of geo plot is plotting the (lon,lat) pairs of a location via `Chart.PointGeo`. +Here is an example using the location of Canadian cities: +*) + +let pointGeo = + Chart.PointGeo( + lon, + lat, + Labels=cityNames, + TextPosition=StyleParam.TextPosition.TopCenter + ) + |> Chart.withMapStyle( + Scope=StyleParam.GeoScope.NorthAmerica, + Projection=GeoProjection.init(StyleParam.GeoProjectionType.AzimuthalEqualArea), + CountryColor = "lightgrey" + ) + |> Chart.withMarginSize(0,0,0,0) + +(*** condition: ipynb ***) +#if IPYNB +pointGeo +#endif // IPYNB + +(***hide***) +pointGeo |> GenericChart.toChartHTML +(***include-it-raw***) + + +(** +To connect the given (lon,lat) pairs via straight lines, use `Chart.LineGeo`. +Below is an example that pulls external data as a Deedle data +frame containing the source and target locations of American Airlines flights from Feb. 2011: +*) + +#r "nuget: Deedle" +#r "nuget: FSharp.Data" +open Deedle +open FSharp.Data +open System.IO +open System.Text + +let data = + Http.RequestString "https://raw.githubusercontent.com/plotly/datasets/c34aaa0b1b3cddad335173cb7bc0181897201ee6/2011_february_aa_flight_paths.csv" + |> fun csv -> Frame.ReadCsvString(csv,true,separators=",") + +let opacityVals : float [] = data.["cnt"] |> Series.values |> fun s -> s |> Seq.map (fun v -> v/(Seq.max s)) |> Array.ofSeq +let startCoords = Series.zipInner data.["start_lon"] data.["start_lat"] +let endCoords = Series.zipInner data.["end_lon"] data.["end_lat"] +let coords = Series.zipInner startCoords endCoords |> Series.values + +let flights = + coords + |> Seq.mapi (fun i (startCoords,endCoords) -> + Chart.LineGeo( + [startCoords; endCoords], + Opacity = opacityVals.[i], + Color = "red" + ) + ) + |> Chart.Combine + |> Chart.withLegend(false) + |> Chart.withMapStyle( + Scope=StyleParam.GeoScope.NorthAmerica, + Projection=GeoProjection.init(StyleParam.GeoProjectionType.AzimuthalEqualArea), + ShowLand=true, + LandColor = "lightgrey" + ) + |> Chart.withMarginSize(0,0,50,0) + |> Chart.withTitle "Feb. 2011 American Airline flights" + +(*** condition: ipynb ***) +#if IPYNB +flights +#endif // IPYNB + +(***hide***) +flights |> GenericChart.toChartHTML +(***include-it-raw***) diff --git a/docs/5_0_choropleth-map.fsx b/docs/5_2_choropleth-map.fsx similarity index 95% rename from docs/5_0_choropleth-map.fsx rename to docs/5_2_choropleth-map.fsx index 4dd1b33ee..f9633356b 100644 --- a/docs/5_0_choropleth-map.fsx +++ b/docs/5_2_choropleth-map.fsx @@ -1,9 +1,9 @@ (** --- title: Choropleth maps -category: Map Charts +category: Geo map charts categoryindex: 6 -index: 1 +index: 3 --- *) @@ -193,10 +193,8 @@ 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") + Http.RequestString "https://raw.githubusercontent.com/plotly/datasets/master/fips-unemp-16.csv" + |> fun csv -> Frame.ReadCsvString(csv,true,separators=",",schema="fips=string,unemp=float") (** @@ -239,7 +237,10 @@ let choroplethGeoJSON = ) |> Chart.withMap( Geo.init( - Scope=StyleParam.GeoScope.Usa + Scope=StyleParam.GeoScope.NorthAmerica, + Projection=GeoProjection.init(StyleParam.GeoProjectionType.AzimuthalEqualArea), + ShowLand=true, + LandColor = "lightgrey" ) ) |> Chart.withSize (800.,800.) diff --git a/docs/6_0_geo-vs-mapbox.fsx b/docs/6_0_geo-vs-mapbox.fsx new file mode 100644 index 000000000..83b99891b --- /dev/null +++ b/docs/6_0_geo-vs-mapbox.fsx @@ -0,0 +1,127 @@ +(** +--- +title: Geo vs. Mapbox +category: Mapbox map charts +categoryindex: 7 +index: 1 +--- +*) + +(*** hide ***) + +(*** condition: prepare ***) +#r "nuget: Newtonsoft.JSON, 12.0.3" +#r "../bin/Plotly.NET/netstandard2.0/Plotly.NET.dll" + +(*** condition: ipynb ***) +#if IPYNB +#r "nuget: Plotly.NET, {{fsdocs-package-version}}" +#r "nuget: Plotly.NET.Interactive, {{fsdocs-package-version}}" +#endif // IPYNB + +(** +# Mapbox Maps vs Geo Maps + +[![Binder]({{root}}img/badge-binder.svg)](https://mybinder.org/v2/gh/plotly/Plotly.NET/gh-pages?filepath={{fsdocs-source-basename}}.ipynb)  +[![Script]({{root}}img/badge-script.svg)]({{root}}{{fsdocs-source-basename}}.fsx)  +[![Notebook]({{root}}img/badge-notebook.svg)]({{root}}{{fsdocs-source-basename}}.ipynb) + +*Summary:* This introduction shows the differences between Geo and Mapbox based geographical charts. + +Plotly and therefore Plotly.NET supports two different kinds of maps: + +- **Mapbox maps** are tile-based maps. If your figure is created with a `Chart.*Mapbox` function or otherwise contains one or more traces of type `scattermapbox`, + `choroplethmapbox` or `densitymapbox`, the layout.mapbox object in your figure contains configuration information for the map itself. + +- **Geo maps** are outline-based maps. If your figure is created with a `Chart.ScatterGeo, `Chart.PointGeo`, `Chart.LineGeo` or `Chart.Choropleth` function or + otherwise contains one or more traces of type `scattergeo` or `choropleth`, the layout.geo object in your figure contains configuration information for the map itself. + +_This page documents Mapbox tile-based maps, and the [Geo map documentation]({{root}}/5_0_geo-vs-mapbox.html) describes how to configure outline-based maps_ + +## How Layers Work in Mapbox Tile Maps + +Mapbox tile maps are composed of various layers, of three different types: + +- the `style` property of the `Mapbox` object defines is the lowest layers, also known as your "base map" +- The various traces in data are by default rendered above the base map (although this can be controlled via the below attribute). +- the `layers` property of the `Mapbox` object is an array that defines more layers that are by default rendered above the traces in data (although this can also be controlled via the below attribute). + +a `Mapbox` object where these properties can be set can be initialized via `Mapbox.init`. To use it in a chart, use the `Chart.withMapbox` function: +*) +open Plotly.NET + +// a simple Mapbox with a OpenStreetMap base layer. +let mb = + Mapbox.init( + Style = StyleParam.MapboxStyle.OpenStreetMap + ) + +let baseLayerOnly = + Chart.PointMapbox([],[]) // deliberately empty chart to show the base map only + |> Chart.withMapbox mb // add the mapBox + +(*** condition: ipynb ***) +#if IPYNB +baseLayerOnly +#endif // IPYNB + +(***hide***) +baseLayerOnly |> GenericChart.toChartHTML +(***include-it-raw***) + +(** + +## Mapbox Access Tokens and When You Need Them + +The word "mapbox" in the trace names and layout.mapbox refers to the Mapbox GL JS open-source library, which is integrated into Plotly.NET. + +If your basemap uses data from the Mapbox service, then you will need to register for a free account at https://mapbox.com/ +and obtain a Mapbox Access token. + +This token should be provided via the `AccessToken` property: +*) + +let mbWithToken = + Mapbox.init( + Style = StyleParam.MapboxStyle.OpenStreetMap, + AccessToken = "your_token_here" + ) + +(** + +If your base map does not use data from the Mapbox service, you do not need to register for a Mapbox account. + +## Base Maps + +- `WhiteBG` yields an empty white canvas which results in no external HTTP requests +- The plotly presets yield maps composed of raster tiles from various public tile servers which do not require signups or access tokens +- The Mapbox presets yield maps composed of vector tiles from the Mapbox service, and do require a Mapbox Access Token or an on-premise Mapbox installation. +- Use `StyleParam.MapboxStyle.Custom` for: + - Mapbox service style URL, which requires a Mapbox Access Token or an on-premise Mapbox installation. + - A Mapbox Style object as defined at https://docs.mapbox.com/mapbox-gl-js/style-spec/ + + +The accepted values for the `style` property of the `Mapbox` object are represented in `StyleParam.MapboxStyle`: + +*) +type MapboxStyle = + // plotly presets, no token needed + | WhiteBG + | OpenStreetMap + | CartoPositron + | CartoDarkmatter + | StamenTerrain + | StamenToner + | StamenWatercolor + + // Mapbox presets, you might need a free token + | MapboxBasic + | MapboxStreets + | MapboxOutdoors + | MapboxLight + | MapboxDark + | MapboxSatellite + | MapboxSatelliteStreets + + //Custom - provide custom maps + | Custom of string \ No newline at end of file diff --git a/docs/6_1_mapbox-plots.fsx b/docs/6_1_mapbox-plots.fsx new file mode 100644 index 000000000..1c2cffee8 --- /dev/null +++ b/docs/6_1_mapbox-plots.fsx @@ -0,0 +1,125 @@ +(** +--- +title: Scatter and line plots on Mapbox maps +category: Mapbox map charts +categoryindex: 7 +index: 2 +--- +*) + +(*** hide ***) + +(*** condition: prepare ***) +#r "nuget: Newtonsoft.JSON, 12.0.3" +#r "../bin/Plotly.NET/netstandard2.0/Plotly.NET.dll" + +(*** condition: ipynb ***) +#if IPYNB +#r "nuget: Plotly.NET, {{fsdocs-package-version}}" +#r "nuget: Plotly.NET.Interactive, {{fsdocs-package-version}}" +#endif // IPYNB + +(** +# Scatter and line plots on Mapbox maps + +[![Binder]({{root}}img/badge-binder.svg)](https://mybinder.org/v2/gh/plotly/Plotly.NET/gh-pages?filepath={{fsdocs-source-basename}}.ipynb)  +[![Script]({{root}}img/badge-script.svg)]({{root}}{{fsdocs-source-basename}}.fsx)  +[![Notebook]({{root}}img/badge-notebook.svg)]({{root}}{{fsdocs-source-basename}}.ipynb) + +*Summary:* This example shows how to create Point and Line charts on Mapbox maps in F#. + +let's first create some data for the purpose of creating example charts: +*) +open Plotly.NET + +let cityNames = [ + "Montreal"; "Toronto"; "Vancouver"; "Calgary"; "Edmonton"; + "Ottawa"; "Halifax"; "Victoria"; "Winnepeg"; "Regina" +] + +let lon = [ + -73.57; -79.24; -123.06; -114.1; -113.28; + -75.43; -63.57; -123.21; -97.13; -104.6 +] +let lat = [ + 45.5; 43.4; 49.13; 51.1; 53.34; 45.24; + 44.64; 48.25; 49.89; 50.45 +] + +(** +The simplest type of geographic plot using Mapbox is plotting the (lon,lat) pairs of a location via `Chart.PointMapbox`. +Here is an example using the location of Canadian cities: +*) + +let pointMapbox = + Chart.PointMapbox( + lon,lat, + Labels = cityNames, + TextPosition = StyleParam.TextPosition.TopCenter + ) + |> Chart.withMapbox( + Mapbox.init( + Style=StyleParam.MapboxStyle.OpenStreetMap, + Center=(-104.6,50.45) + ) + ) + +(*** condition: ipynb ***) +#if IPYNB +pointMapbox +#endif // IPYNB + +(***hide***) +pointMapbox |> GenericChart.toChartHTML +(***include-it-raw***) + +(** +To connect the given (lon,lat) pairs via straight lines, use `Chart.LineGeo`. +Below is an example that pulls external data as a Deedle data +frame containing the source and target locations of American Airlines flights from Feb. 2011: +*) + +#r "nuget: Deedle" +#r "nuget: FSharp.Data" +open Deedle +open FSharp.Data +open System.IO +open System.Text + +let data = + Http.RequestString "https://raw.githubusercontent.com/plotly/datasets/c34aaa0b1b3cddad335173cb7bc0181897201ee6/2011_february_aa_flight_paths.csv" + |> fun csv -> Frame.ReadCsvString(csv,true,separators=",") + +let opacityVals : float [] = data.["cnt"] |> Series.values |> fun s -> s |> Seq.map (fun v -> v/(Seq.max s)) |> Array.ofSeq +let startCoords = Series.zipInner data.["start_lon"] data.["start_lat"] +let endCoords = Series.zipInner data.["end_lon"] data.["end_lat"] +let coords = Series.zipInner startCoords endCoords |> Series.values + +let flights = + coords + |> Seq.mapi (fun i (startCoords,endCoords) -> + Chart.LineMapbox( + [startCoords; endCoords], + Opacity = opacityVals.[i], + Color = "red" + ) + ) + |> Chart.Combine + |> Chart.withLegend(false) + |> Chart.withMapbox( + Mapbox.init( + Style=StyleParam.MapboxStyle.OpenStreetMap, + Center=(-97.0372,32.8959) + ) + ) + |> Chart.withMarginSize(0,0,50,0) + |> Chart.withTitle "Feb. 2011 American Airline flights" + +(*** condition: ipynb ***) +#if IPYNB +flights +#endif // IPYNB + +(***hide***) +flights |> GenericChart.toChartHTML +(***include-it-raw***) diff --git a/docs/6_2_choropleth-mapbox.fsx b/docs/6_2_choropleth-mapbox.fsx new file mode 100644 index 000000000..cbaedc850 --- /dev/null +++ b/docs/6_2_choropleth-mapbox.fsx @@ -0,0 +1,148 @@ +(** +--- +title: ChoroplethMapbox +category: Mapbox map charts +categoryindex: 7 +index: 3 +--- +*) + +(*** hide ***) + +(*** condition: prepare ***) +#r "nuget: Newtonsoft.JSON, 12.0.3" +#r "../bin/Plotly.NET/netstandard2.0/Plotly.NET.dll" + +(*** condition: ipynb ***) +#if IPYNB +#r "nuget: Plotly.NET, {{fsdocs-package-version}}" +#r "nuget: Plotly.NET.Interactive, {{fsdocs-package-version}}" +#endif // IPYNB + +(** +# ChoroplethMapbox + +[![Binder]({{root}}img/badge-binder.svg)](https://mybinder.org/v2/gh/plotly/Plotly.NET/gh-pages?filepath={{fsdocs-source-basename}}.ipynb)  +[![Script]({{root}}img/badge-script.svg)]({{root}}{{fsdocs-source-basename}}.fsx)  +[![Notebook]({{root}}img/badge-notebook.svg)]({{root}}{{fsdocs-source-basename}}.ipynb) + +*Summary:* This example shows how to create choropleth maps using Mapbox layers in F#. + +Choropleth Maps display divided geographical areas or regions that are coloured, shaded or patterned in relation to +a data variable. This provides a way to visualise values over a geographical area, which can show variation or +patterns across the displayed location. + +This choropleth map version uses [Mapbox Layers]({{root}}/6_0_geo-vs-mapbox.html). For the Geo variant, head over [here]({{root}}/5_2_choropleth-map.html) + +ChoroplethMapbox charts need GeoJSON formatted data. + +[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 + +let data = + Http.RequestString "https://raw.githubusercontent.com/plotly/datasets/master/fips-unemp-16.csv" + |> fun csv -> Frame.ReadCsvString(csv,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 locations: string [] = + data + |> Frame.getCol "fips" + |> Series.values + |> Array.ofSeq + +let z: int [] = + data + |> Frame.getCol "unemp" + |> Series.values + |> Array.ofSeq + + +(** +And finally put together the chart using GeoJSON: +*) + +open Plotly.NET + +let choroplethMapbox = + Chart.ChoroplethMapbox( + locations = locations, + z = z, + geoJson = geoJson, + FeatureIdKey="id" + ) + |> Chart.withMapbox( + Mapbox.init( + Style=StyleParam.MapboxStyle.OpenStreetMap, // Use the free open street map base map layer + Center=(-104.6,50.45) + ) + ) + +(*** condition: ipynb ***) +#if IPYNB +choroplethMapbox +#endif // IPYNB + +(***hide***) +choroplethMapbox |> GenericChart.toChartHTML +(***include-it-raw***) \ No newline at end of file diff --git a/docs/6_3_density-mapbox.fsx b/docs/6_3_density-mapbox.fsx new file mode 100644 index 000000000..43bd88f63 --- /dev/null +++ b/docs/6_3_density-mapbox.fsx @@ -0,0 +1,75 @@ +(** +--- +title: DensityMapbox charts +category: Mapbox map charts +categoryindex: 7 +index: 4 +--- +*) + +(*** hide ***) + +(*** condition: prepare ***) +#r "nuget: Newtonsoft.JSON, 12.0.3" +#r "../bin/Plotly.NET/netstandard2.0/Plotly.NET.dll" + +(*** condition: ipynb ***) +#if IPYNB +#r "nuget: Plotly.NET, {{fsdocs-package-version}}" +#r "nuget: Plotly.NET.Interactive, {{fsdocs-package-version}}" +#endif // IPYNB + +(** +# DensityMapbox charts + +[![Binder]({{root}}img/badge-binder.svg)](https://mybinder.org/v2/gh/plotly/Plotly.NET/gh-pages?filepath={{fsdocs-source-basename}}.ipynb)  +[![Script]({{root}}img/badge-script.svg)]({{root}}{{fsdocs-source-basename}}.fsx)  +[![Notebook]({{root}}img/badge-notebook.svg)]({{root}}{{fsdocs-source-basename}}.ipynb) + +*Summary:* This example shows how to create DensityMapbox charts in F#. + +`Chart.DensityMapbox` draws a bivariate kernel density estimation with a Gaussian kernel from `lon` and `lat` coordinates and optional `z` values using a colorscale. +This Chart uses [Mapbox layers]({{root}}/6_0_geo-vs-mapbox.html) and might need a Mapbox API token depending on the desired base map layer style. + +*) +// we are using the awesome FSharp.Data project here to perform a http request, +// and the awesome Deedle library to read the data as a data frame +#r "nuget: FSharp.Data" +#r "nuget: Deedle" + +open FSharp.Data +open Deedle + +let dataDensityMapbox = + Http.RequestString "https://raw.githubusercontent.com/plotly/datasets/master/earthquakes-23k.csv" + |> fun d -> Frame.ReadCsvString(d,true,separators=",") + +let lon = dataDensityMapbox.["Longitude"] |> Series.values +let lat= dataDensityMapbox.["Latitude"] |> Series.values +let magnitudes = dataDensityMapbox.["Magnitude"] |> Series.values + +open Plotly.NET + +let densityMapbox = + Chart.DensityMapbox( + lon, + lat, + Z = magnitudes, + Radius=8., + Colorscale=StyleParam.Colorscale.Viridis + ) + |> Chart.withMapbox( + Mapbox.init( + Style = StyleParam.MapboxStyle.StamenTerrain, + Center = (60.,30.) + ) + ) + +(*** condition: ipynb ***) +#if IPYNB +densityMapbox +#endif // IPYNB + +(***hide***) +densityMapbox |> GenericChart.toChartHTML +(***include-it-raw***) \ No newline at end of file diff --git a/docs/6_0_candlestick.fsx b/docs/7_0_candlestick.fsx similarity index 99% rename from docs/6_0_candlestick.fsx rename to docs/7_0_candlestick.fsx index 7594166ec..d0a9f4365 100644 --- a/docs/6_0_candlestick.fsx +++ b/docs/7_0_candlestick.fsx @@ -2,7 +2,7 @@ --- title: Candlestick Charts category: Finance Charts -categoryindex: 7 +categoryindex: 8 index: 1 --- *) diff --git a/docs/6_1_funnel.fsx b/docs/7_1_funnel.fsx similarity index 100% rename from docs/6_1_funnel.fsx rename to docs/7_1_funnel.fsx diff --git a/docs/6_2_funnel_area.fsx b/docs/7_2_funnel_area.fsx similarity index 100% rename from docs/6_2_funnel_area.fsx rename to docs/7_2_funnel_area.fsx diff --git a/docs/7_0_polar-charts.fsx b/docs/8_0_polar-charts.fsx similarity index 100% rename from docs/7_0_polar-charts.fsx rename to docs/8_0_polar-charts.fsx diff --git a/docs/7_1_windrose-charts.fsx b/docs/8_1_windrose-charts.fsx similarity index 100% rename from docs/7_1_windrose-charts.fsx rename to docs/8_1_windrose-charts.fsx diff --git a/docs/8_0_parallel-categories.fsx b/docs/9_0_parallel-categories.fsx similarity index 100% rename from docs/8_0_parallel-categories.fsx rename to docs/9_0_parallel-categories.fsx diff --git a/docs/8_1_parallel-coords.fsx b/docs/9_1_parallel-coords.fsx similarity index 100% rename from docs/8_1_parallel-coords.fsx rename to docs/9_1_parallel-coords.fsx diff --git a/docs/8_2_sankey.fsx b/docs/9_2_sankey.fsx similarity index 100% rename from docs/8_2_sankey.fsx rename to docs/9_2_sankey.fsx diff --git a/docs/content/fsdocs-custom.css b/docs/content/fsdocs-custom.css index 773e9b620..39c42d60d 100644 --- a/docs/content/fsdocs-custom.css +++ b/docs/content/fsdocs-custom.css @@ -8975,8 +8975,11 @@ a.has-text-danger-dark:hover, a.has-text-danger-dark:focus { border: none; } } .nav-header { - list-style: none; - color: #A00975; } + list-style: none; + color: #A00975; + border-bottom: 1px dashed #A00975; + margin-right: 1em +} #fsdocs-content h1 a, #fsdocs-content h1 a:hover, #fsdocs-content h1 a:focus, #fsdocs-content h2 a, #fsdocs-content h2 a:hover, #fsdocs-content h2 a:focus, diff --git a/src/Plotly.NET/Chart.fs b/src/Plotly.NET/Chart.fs index c6416910c..24fd84028 100644 --- a/src/Plotly.NET/Chart.fs +++ b/src/Plotly.NET/Chart.fs @@ -2782,6 +2782,7 @@ type Chart = /// Fill : Sets the area to fill with a solid color. Use with `fillcolor` if not "none". "toself" connects the endpoints of the trace (or each segment of the trace if it has gaps) into a closed shape. /// /// Fillcolor : Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. + static member LineGeo(locations, [] ?Name , [] ?Showlegend , @@ -2821,4 +2822,510 @@ type Chart = |> TraceStyle.TraceInfo(?Name=Name,?Showlegend=Showlegend,?Opacity=Opacity) |> TraceStyle.Marker(?Color=Color,?Symbol=MarkerSymbol) |> TraceStyle.TextLabel(?Text=Labels,?Textposition=TextPosition,?Textfont=TextFont) - |> GenericChart.ofTraceObject \ No newline at end of file + |> GenericChart.ofTraceObject + + /// + /// Creates a ScatterMapbox chart, where data is visualized by (longitude,latitude) pairs on a geographic map using mapbox. + /// + /// Customize the mapbox layers, style, etc. by using Chart.withMapbox. + /// + /// You might need a Mapbox token, which you can also configure with Chart.withMapbox. + /// + /// ScatterGeo charts are the basis of PointMapbox and LineMapbox Charts, and can be customized as such. We also provide abstractions for those: Chart.PointMapbox and Chart.LineMapbox + /// + /// Sets the longitude coordinates (in degrees East). + /// Sets the latitude coordinates (in degrees North). + /// Determines the drawing mode for this scatter trace. If the provided `mode` includes "text" then the `text` elements appear at the coordinates. Otherwise, the `text` elements appear on hover. + /// Sets the trace name. The trace name appear as the legend item and on hover. + /// Determines whether or not an item corresponding to this trace is shown in the legend. + /// Sets the marker color. It accepts either a specific color or an array of numbers that are mapped to the colorscale relative to the max and min values of the array or relative to `marker.cmin` and `marker.cmax` if set. + /// Sets the opacity of the trace. + /// Sets text elements associated with each (lon,lat) pair If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (lon,lat) coordinates. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. + /// Sets the positions of the `text` elements with respects to the (x,y) coordinates. + /// Sets the icon text font (color=mapbox.layer.paint.text-color, size=mapbox.layer.layout.text-size). Has an effect only when `type` is set to "symbol". + /// Sets the line width (in px). + /// Determines if this scattermapbox trace's layers are to be inserted before the layer with the specified ID. By default, scattermapbox layers are inserted above all the base layers. To place the scattermapbox layers above every other layer, set `below` to "''". + /// Determines whether or not gaps (i.e. {nan} or missing values) in the provided data arrays are connected. + /// Sets the area to fill with a solid color. Use with `fillcolor` if not "none". "toself" connects the endpoints of the trace (or each segment of the trace if it has gaps) into a closed shape. + /// Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. + static member ScatterMapbox(longitudes, latitudes, mode, + [] ?Name , + [] ?ShowLegend , + [] ?Color , + [] ?Opacity , + [] ?Labels , + [] ?TextPosition , + [] ?TextFont , + [] ?Width : float , + [] ?Below : string , + [] ?Connectgaps : bool , + [] ?Fill : StyleParam.Fill , + [] ?Fillcolor + ) = + + Trace.initScatterMapbox( + TraceStyle.ScatterMapbox( + mode = mode , + Longitudes = longitudes , + Latitudes = latitudes , + ?Below = Below , + ?Connectgaps = Connectgaps , + ?Fill = Fill , + ?Fillcolor = Fillcolor + ) + ) + |> TraceStyle.TraceInfo(?Name=Name,?Showlegend=ShowLegend,?Opacity=Opacity) + |> TraceStyle.Line(?Color=Color,?Width=Width) + |> TraceStyle.Marker(?Color=Color) + |> TraceStyle.TextLabel(?Text=Labels,?Textposition=TextPosition,?Textfont=TextFont) + |> GenericChart.ofTraceObject + + /// + /// Creates a ScatterMapbox chart, where data is visualized by (longitude,latitude) pairs on a geographic map using mapbox. + /// + /// Customize the mapbox layers, style, etc. by using Chart.withMapbox. + /// + /// You might need a Mapbox token, which you can also configure with Chart.withMapbox. + /// + /// ScatterGeo charts are the basis of PointMapbox and LineMapbox Charts, and can be customized as such. We also provide abstractions for those: Chart.PointMapbox and Chart.LineMapbox + /// + /// Sets the (longitude,latitude) coordinates (in degrees North, degrees South). + /// Determines the drawing mode for this scatter trace. If the provided `mode` includes "text" then the `text` elements appear at the coordinates. Otherwise, the `text` elements appear on hover. + /// Sets the trace name. The trace name appear as the legend item and on hover. + /// Determines whether or not an item corresponding to this trace is shown in the legend. + /// Sets the marker color. It accepts either a specific color or an array of numbers that are mapped to the colorscale relative to the max and min values of the array or relative to `marker.cmin` and `marker.cmax` if set. + /// Sets the opacity of the trace. + /// Sets text elements associated with each (lon,lat) pair If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (lon,lat) coordinates. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. + /// Sets the positions of the `text` elements with respects to the (x,y) coordinates. + /// Sets the icon text font (color=mapbox.layer.paint.text-color, size=mapbox.layer.layout.text-size). Has an effect only when `type` is set to "symbol". + /// Sets the line width (in px). + /// Determines if this scattermapbox trace's layers are to be inserted before the layer with the specified ID. By default, scattermapbox layers are inserted above all the base layers. To place the scattermapbox layers above every other layer, set `below` to "''". + /// Determines whether or not gaps (i.e. {nan} or missing values) in the provided data arrays are connected. + /// Sets the area to fill with a solid color. Use with `fillcolor` if not "none". "toself" connects the endpoints of the trace (or each segment of the trace if it has gaps) into a closed shape. + /// Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. + static member ScatterMapbox(lonlat, mode, + [] ?Name , + [] ?ShowLegend , + [] ?Color , + [] ?Opacity , + [] ?Labels , + [] ?TextPosition , + [] ?TextFont , + [] ?Width : float , + [] ?Below : string , + [] ?Connectgaps : bool , + [] ?Fill : StyleParam.Fill , + [] ?Fillcolor + ) = + + let longitudes, latitudes = Seq.unzip lonlat + + Chart.ScatterMapbox( + longitudes, + latitudes, + mode, + ?Name = Name , + ?ShowLegend = ShowLegend , + ?Color = Color , + ?Opacity = Opacity , + ?Labels = Labels , + ?TextPosition= TextPosition, + ?TextFont = TextFont , + ?Width = Width , + ?Below = Below , + ?Connectgaps = Connectgaps, + ?Fill = Fill , + ?Fillcolor = Fillcolor + ) + + /// + /// Creates a PointMapbox chart, where data is visualized by (longitude,latitude) pairs as Points on a geographic map using mapbox. + /// + /// Customize the mapbox layers, style, etc. by using Chart.withMapbox. + /// + /// You might need a Mapbox token, which you can also configure with Chart.withMapbox. + /// + /// Sets the longitude coordinates (in degrees East). + /// Sets the latitude coordinates (in degrees North). + /// Sets the trace name. The trace name appear as the legend item and on hover. + /// Determines whether or not an item corresponding to this trace is shown in the legend. + /// Sets the marker color. It accepts either a specific color or an array of numbers that are mapped to the colorscale relative to the max and min values of the array or relative to `marker.cmin` and `marker.cmax` if set. + /// Sets the opacity of the trace. + /// Sets text elements associated with each (lon,lat) pair If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (lon,lat) coordinates. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. + /// Sets the positions of the `text` elements with respects to the (x,y) coordinates. + /// Sets the icon text font (color=mapbox.layer.paint.text-color, size=mapbox.layer.layout.text-size). Has an effect only when `type` is set to "symbol". + /// Sets the line width (in px). + /// Determines if this scattermapbox trace's layers are to be inserted before the layer with the specified ID. By default, scattermapbox layers are inserted above all the base layers. To place the scattermapbox layers above every other layer, set `below` to "''". + /// Determines whether or not gaps (i.e. {nan} or missing values) in the provided data arrays are connected. + /// Sets the area to fill with a solid color. Use with `fillcolor` if not "none". "toself" connects the endpoints of the trace (or each segment of the trace if it has gaps) into a closed shape. + /// Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. + static member PointMapbox(longitudes,latitudes, + [] ?Name , + [] ?ShowLegend , + [] ?Color , + [] ?Opacity , + [] ?Labels , + [] ?TextPosition , + [] ?TextFont , + [] ?Width : float , + [] ?Below : string , + [] ?Connectgaps : bool , + [] ?Fill : StyleParam.Fill , + [] ?Fillcolor + ) = + + let changeMode = StyleParam.ModeUtils.showText (TextPosition.IsSome || TextFont.IsSome) + + Chart.ScatterMapbox( + longitudes, + latitudes, + mode = changeMode StyleParam.Mode.Markers , + ?Name = Name , + ?ShowLegend = ShowLegend , + ?Color = Color , + ?Opacity = Opacity , + ?Labels = Labels , + ?TextPosition= TextPosition, + ?TextFont = TextFont , + ?Width = Width , + ?Below = Below , + ?Connectgaps = Connectgaps, + ?Fill = Fill , + ?Fillcolor = Fillcolor + ) + + /// + /// Creates a PointMapbox chart, where data is visualized by (longitude,latitude) pairs as Points on a geographic map using mapbox. + /// + /// Customize the mapbox layers, style, etc. by using Chart.withMapbox. + /// + /// You might need a Mapbox token, which you can also configure with Chart.withMapbox. + /// + /// Sets the (longitude,latitude) coordinates (in degrees North, degrees South). + /// Sets the trace name. The trace name appear as the legend item and on hover. + /// Determines whether or not an item corresponding to this trace is shown in the legend. + /// Sets the marker color. It accepts either a specific color or an array of numbers that are mapped to the colorscale relative to the max and min values of the array or relative to `marker.cmin` and `marker.cmax` if set. + /// Sets the opacity of the trace. + /// Sets text elements associated with each (lon,lat) pair If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (lon,lat) coordinates. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. + /// Sets the positions of the `text` elements with respects to the (x,y) coordinates. + /// Sets the icon text font (color=mapbox.layer.paint.text-color, size=mapbox.layer.layout.text-size). Has an effect only when `type` is set to "symbol". + /// Sets the line width (in px). + /// Determines if this scattermapbox trace's layers are to be inserted before the layer with the specified ID. By default, scattermapbox layers are inserted above all the base layers. To place the scattermapbox layers above every other layer, set `below` to "''". + /// Determines whether or not gaps (i.e. {nan} or missing values) in the provided data arrays are connected. + /// Sets the area to fill with a solid color. Use with `fillcolor` if not "none". "toself" connects the endpoints of the trace (or each segment of the trace if it has gaps) into a closed shape. + /// Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. + static member PointMapbox(lonlat, + [] ?Name , + [] ?ShowLegend , + [] ?Color , + [] ?Opacity , + [] ?Labels , + [] ?TextPosition , + [] ?TextFont , + [] ?Width : float , + [] ?Below : string , + [] ?Connectgaps : bool , + [] ?Fill : StyleParam.Fill , + [] ?Fillcolor + ) = + + let changeMode = StyleParam.ModeUtils.showText (TextPosition.IsSome || TextFont.IsSome) + let longitudes, latitudes = Seq.unzip lonlat + + Chart.ScatterMapbox( + longitudes, + latitudes, + mode = changeMode StyleParam.Mode.Markers , + ?Name = Name , + ?ShowLegend = ShowLegend , + ?Color = Color , + ?Opacity = Opacity , + ?Labels = Labels , + ?TextPosition= TextPosition, + ?TextFont = TextFont , + ?Width = Width , + ?Below = Below , + ?Connectgaps = Connectgaps, + ?Fill = Fill , + ?Fillcolor = Fillcolor + ) + /// + /// Creates a LineMapbox chart, where data is visualized by (longitude,latitude) pairs connected by a line on a geographic map using mapbox. + /// + /// Customize the mapbox layers, style, etc. by using Chart.withMapbox. + /// + /// You might need a Mapbox token, which you can also configure with Chart.withMapbox. + /// + /// Sets the longitude coordinates (in degrees East). + /// Sets the latitude coordinates (in degrees North). + /// Sets the trace name. The trace name appear as the legend item and on hover. + /// Determines whether or not an item corresponding to this trace is shown in the legend. + /// Determines whether or not To show markers for the individual datums. + /// Sets the marker color. It accepts either a specific color or an array of numbers that are mapped to the colorscale relative to the max and min values of the array or relative to `marker.cmin` and `marker.cmax` if set. + /// Sets the opacity of the trace. + /// Sets text elements associated with each (lon,lat) pair If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (lon,lat) coordinates. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. + /// Sets the positions of the `text` elements with respects to the (x,y) coordinates. + /// Sets the icon text font (color=mapbox.layer.paint.text-color, size=mapbox.layer.layout.text-size). Has an effect only when `type` is set to "symbol". + /// Sets the line width (in px). + /// Determines if this scattermapbox trace's layers are to be inserted before the layer with the specified ID. By default, scattermapbox layers are inserted above all the base layers. To place the scattermapbox layers above every other layer, set `below` to "''". + /// Determines whether or not gaps (i.e. {nan} or missing values) in the provided data arrays are connected. + /// Sets the area to fill with a solid color. Use with `fillcolor` if not "none". "toself" connects the endpoints of the trace (or each segment of the trace if it has gaps) into a closed shape. + /// Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. + static member LineMapbox(longitudes,latitudes, + [] ?Name , + [] ?ShowLegend , + [] ?ShowMarkers , + [] ?Color , + [] ?Opacity , + [] ?Labels , + [] ?TextPosition , + [] ?TextFont , + [] ?Width : float , + [] ?Below : string , + [] ?Connectgaps : bool , + [] ?Fill : StyleParam.Fill , + [] ?Fillcolor + ) = + + + let changeMode = + let isShowMarker = + match ShowMarkers with + | Some isShow -> isShow + | Option.None -> false + StyleParam.ModeUtils.showText (TextPosition.IsSome || TextFont.IsSome) + >> StyleParam.ModeUtils.showMarker (isShowMarker) + + Chart.ScatterMapbox( + longitudes, + latitudes, + mode = changeMode StyleParam.Mode.Lines , + ?Name = Name , + ?ShowLegend = ShowLegend , + ?Color = Color , + ?Opacity = Opacity , + ?Labels = Labels , + ?TextPosition= TextPosition, + ?TextFont = TextFont , + ?Width = Width , + ?Below = Below , + ?Connectgaps = Connectgaps, + ?Fill = Fill , + ?Fillcolor = Fillcolor + ) + + /// + /// Creates a LineMapbox chart, where data is visualized by (longitude,latitude) pairs connected by a line on a geographic map using mapbox. + /// + /// Customize the mapbox layers, style, etc. by using Chart.withMapbox. + /// + /// You might need a Mapbox token, which you can also configure with Chart.withMapbox. + /// + /// Sets the (longitude,latitude) coordinates (in degrees North, degrees South). + /// Sets the trace name. The trace name appear as the legend item and on hover. + /// Determines whether or not an item corresponding to this trace is shown in the legend. + /// Determines whether or not To show markers for the individual datums. + /// Sets the marker color. It accepts either a specific color or an array of numbers that are mapped to the colorscale relative to the max and min values of the array or relative to `marker.cmin` and `marker.cmax` if set. + /// Sets the opacity of the trace. + /// Sets text elements associated with each (lon,lat) pair If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (lon,lat) coordinates. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. + /// Sets the positions of the `text` elements with respects to the (x,y) coordinates. + /// Sets the icon text font (color=mapbox.layer.paint.text-color, size=mapbox.layer.layout.text-size). Has an effect only when `type` is set to "symbol". + /// Sets the line width (in px). + /// Determines if this scattermapbox trace's layers are to be inserted before the layer with the specified ID. By default, scattermapbox layers are inserted above all the base layers. To place the scattermapbox layers above every other layer, set `below` to "''". + /// Determines whether or not gaps (i.e. {nan} or missing values) in the provided data arrays are connected. + /// Sets the area to fill with a solid color. Use with `fillcolor` if not "none". "toself" connects the endpoints of the trace (or each segment of the trace if it has gaps) into a closed shape. + /// Sets the fill color. Defaults to a half-transparent variant of the line color, marker color, or marker line color, whichever is available. + static member LineMapbox(lonlat, + [] ?Name , + [] ?ShowLegend , + [] ?ShowMarkers , + [] ?Color , + [] ?Opacity , + [] ?Labels , + [] ?TextPosition , + [] ?TextFont , + [] ?Width : float , + [] ?Below : string , + [] ?Connectgaps : bool , + [] ?Fill : StyleParam.Fill , + [] ?Fillcolor + ) = + + let changeMode = + let isShowMarker = + match ShowMarkers with + | Some isShow -> isShow + | Option.None -> false + StyleParam.ModeUtils.showText (TextPosition.IsSome || TextFont.IsSome) + >> StyleParam.ModeUtils.showMarker (isShowMarker) + let longitudes, latitudes = Seq.unzip lonlat + + Chart.ScatterMapbox( + longitudes, + latitudes, + mode = changeMode StyleParam.Mode.Lines , + ?Name = Name , + ?ShowLegend = ShowLegend , + ?Color = Color , + ?Opacity = Opacity , + ?Labels = Labels , + ?TextPosition= TextPosition, + ?TextFont = TextFont , + ?Width = Width , + ?Below = Below , + ?Connectgaps = Connectgaps, + ?Fill = Fill , + ?Fillcolor = Fillcolor + ) + + /// + /// Creates a ChoroplethMapbox Chart. + /// + /// Choropleth Maps display divided geographical areas or regions that are coloured, shaded or patterned in relation to + /// a data variable. This provides a way to visualise values over a geographical area, which can show variation or + /// patterns across the displayed location. + /// + /// GeoJSON features to be filled are set in `geojson` The data that describes the choropleth value-to-color mapping is set in `locations` and `z`. + /// + /// Sets which features found in "geojson" to plot using their feature `id` field. + /// Sets the color values. + /// Sets the GeoJSON data associated with this trace. It can be set as a valid GeoJSON object or as a URL string. Note that we only accept GeoJSONs of type "FeatureCollection" or "Feature" with geometries of type "Polygon" or "MultiPolygon". + /// Sets the key in GeoJSON features which is used as id to match the items included in the `locations` array. Support nested property, for example "properties.name". + /// Sets the text elements associated with each location. + /// Determines if the choropleth polygons will be inserted before the layer with the specified ID. By default, choroplethmapbox traces are placed above the water layers. If set to '', the layer will be inserted above every existing layer. + /// Sets the colorscale. + /// Sets the Colorbar object asociated with this trace + /// Determines whether or not the color domain is computed with respect to the input data (here in `z`) or the bounds set in `zmin` and `zmax` Defaults to `false` when `zmin` and `zmax` are set by the user. + /// Sets the lower bound of the color domain. Value should have the same units as in `z` and if set, `zmax` must be set as well. + /// Sets the mid-point of the color domain by scaling `zmin` and/or `zmax` to be equidistant to this point. Value should have the same units as in `z`. Has no effect when `zauto` is `false`. + /// Sets the upper bound of the color domain. Value should have the same units as in `z` and if set, `zmin` must be set as well. + static member ChoroplethMapbox(locations,z,geoJson, + [] ?FeatureIdKey, + [] ?Text, + [] ?Below, + [] ?Colorscale, + [] ?Colorbar, + [] ?ZAuto, + [] ?ZMin, + [] ?ZMid, + [] ?ZMax + ) = + + Trace.initChoroplethMapbox ( + TraceStyle.ChoroplethMapbox ( + Z = z, + Locations = locations, + GeoJson = geoJson, + ?FeatureIdKey = FeatureIdKey, + ?Text = Text, + ?Below = Below, + ?Colorscale = Colorscale, + ?Colorbar = Colorbar, + ?ZAuto = ZAuto, + ?ZMin = ZMin, + ?ZMid = ZMid, + ?ZMax = ZMax + ) + ) + |> GenericChart.ofTraceObject + + /// + /// Creates a DensityMapbox Chart that draws a bivariate kernel density estimation with a Gaussian kernel from `lon` and `lat` coordinates and optional `z` values using a colorscale. + /// + /// Sets the longitude coordinates (in degrees East). + /// Sets the latitude coordinates (in degrees North). + /// Sets the points' weight. For example, a value of 10 would be equivalent to having 10 points of weight 1 in the same spot + /// Sets the radius of influence of one `lon` / `lat` point in pixels. Increasing the value makes the densitymapbox trace smoother, but less detailed. + /// Sets the opacity of the trace. + /// Sets text elements associated with each (lon,lat) pair If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (lon,lat) coordinates. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. + /// Determines if the densitymapbox trace will be inserted before the layer with the specified ID. By default, densitymapbox traces are placed below the first layer of type symbol If set to '', the layer will be inserted above every existing layer. + /// Sets the colorscale. + /// Sets the Colorbar object asociated with this trace + /// Determines whether or not a colorbar is displayed for this trace. + /// Determines whether or not the color domain is computed with respect to the input data (here in `z`) or the bounds set in `zmin` and `zmax` Defaults to `false` when `zmin` and `zmax` are set by the user. + /// Sets the lower bound of the color domain. Value should have the same units as in `z` and if set, `zmax` must be set as well. + /// Sets the mid-point of the color domain by scaling `zmin` and/or `zmax` to be equidistant to this point. Value should have the same units as in `z`. Has no effect when `zauto` is `false`. + /// Sets the upper bound of the color domain. Value should have the same units as in `z` and if set, `zmin` must be set as well. + static member DensityMapbox (lon,lat, + [] ?Z, + [] ?Radius, + [] ?Opacity, + [] ?Text, + [] ?Below, + [] ?Colorscale, + [] ?Colorbar, + [] ?Showscale , + [] ?ZAuto, + [] ?ZMin, + [] ?ZMid, + [] ?ZMax + ) = + Trace.initDensityMapbox( + TraceStyle.DensityMapbox( + Longitudes = lon, + Latitudes = lat, + ?Z = Z, + ?Radius = Radius, + ?Opacity = Opacity, + ?Text = Text, + ?Below = Below, + ?Colorscale = Colorscale, + ?Colorbar = Colorbar, + ?Showscale = Showscale, + ?ZAuto = ZAuto, + ?ZMin = ZMin, + ?ZMid = ZMid, + ?ZMax = ZMax + ) + ) + |> GenericChart.ofTraceObject + + /// + /// Creates a DensityMapbox Chart that draws a bivariate kernel density estimation with a Gaussian kernel from `lon` and `lat` coordinates and optional `z` values using a colorscale. + /// + /// Sets the (longitude,latitude) coordinates (in degrees North, degrees South). + /// Sets the points' weight. For example, a value of 10 would be equivalent to having 10 points of weight 1 in the same spot + /// Sets the radius of influence of one `lon` / `lat` point in pixels. Increasing the value makes the densitymapbox trace smoother, but less detailed. + /// Sets the opacity of the trace. + /// Sets text elements associated with each (lon,lat) pair If a single string, the same string appears over all the data points. If an array of string, the items are mapped in order to the this trace's (lon,lat) coordinates. If trace `hoverinfo` contains a "text" flag and "hovertext" is not set, these elements will be seen in the hover labels. + /// Determines if the densitymapbox trace will be inserted before the layer with the specified ID. By default, densitymapbox traces are placed below the first layer of type symbol If set to '', the layer will be inserted above every existing layer. + /// Sets the colorscale. + /// Sets the Colorbar object asociated with this trace + /// Determines whether or not a colorbar is displayed for this trace. + /// Determines whether or not the color domain is computed with respect to the input data (here in `z`) or the bounds set in `zmin` and `zmax` Defaults to `false` when `zmin` and `zmax` are set by the user. + /// Sets the lower bound of the color domain. Value should have the same units as in `z` and if set, `zmax` must be set as well. + /// Sets the mid-point of the color domain by scaling `zmin` and/or `zmax` to be equidistant to this point. Value should have the same units as in `z`. Has no effect when `zauto` is `false`. + /// Sets the upper bound of the color domain. Value should have the same units as in `z` and if set, `zmin` must be set as well. + static member DensityMapbox (lonlat, + [] ?Z, + [] ?Radius, + [] ?Opacity, + [] ?Text, + [] ?Below, + [] ?Colorscale, + [] ?Colorbar, + [] ?Showscale , + [] ?ZAuto, + [] ?ZMin, + [] ?ZMid, + [] ?ZMax + ) = + + let longitudes, latitudes = Seq.unzip lonlat + + Chart.DensityMapbox( + longitudes, + latitudes, + ?Z = Z, + ?Radius = Radius, + ?Opacity = Opacity, + ?Text = Text, + ?Below = Below, + ?Colorscale = Colorscale, + ?Colorbar = Colorbar, + ?Showscale = Showscale, + ?ZAuto = ZAuto, + ?ZMin = ZMin, + ?ZMid = ZMid, + ?ZMax = ZMax + ) \ No newline at end of file diff --git a/src/Plotly.NET/ChartExtensions.fs b/src/Plotly.NET/ChartExtensions.fs index 1d26c64e3..ec75eb741 100644 --- a/src/Plotly.NET/ChartExtensions.fs +++ b/src/Plotly.NET/ChartExtensions.fs @@ -400,6 +400,17 @@ module ChartExtensions = GenericChart.setLayout layout ch ) + /// Sets a mapbox for the given chart (will only work with traces supporting mapboxes, e.g. choroplethmapbox, scattermapbox) + [] + static member withMapbox(mapBox:Mapbox,[] ?Id ) = + (fun (ch:GenericChart) -> + let layout = + let id = defaultArg Id 1 + GenericChart.getLayout ch + |> Layout.UpdateMapboxById(id,mapBox) + GenericChart.setLayout layout ch + ) + /// Sets the map style for the given chart (will only work with traces supporting geo, e.g. choropleth, scattergeo) /// /// Parameters : diff --git a/src/Plotly.NET/GenericChartExtensions.fs b/src/Plotly.NET/GenericChartExtensions.fs index 1118459ed..a20a04630 100644 --- a/src/Plotly.NET/GenericChartExtensions.fs +++ b/src/Plotly.NET/GenericChartExtensions.fs @@ -335,6 +335,16 @@ module GenericChartExtensions = |> Layout.UpdateMapById(id,map) GenericChart.setLayout layout this + /// Sets a mapbox for the given chart (will only work with traces supporting mapboxes, e.g. choroplethmapbox, scattermapbox) + [] + [] + member this.withMapbox(mapBox:Mapbox,[] ?Id ) = + let layout = + let id = defaultArg Id 1 + GenericChart.getLayout this + |> Layout.UpdateMapboxById(id,mapBox) + GenericChart.setLayout layout this + /// Sets the map style for the given chart (will only work with traces supporting geo, e.g. choropleth, scattergeo) /// diff --git a/src/Plotly.NET/Layout.fs b/src/Plotly.NET/Layout.fs index fdd7e14fe..34fe3e0ed 100644 --- a/src/Plotly.NET/Layout.fs +++ b/src/Plotly.NET/Layout.fs @@ -300,7 +300,7 @@ type Layout() = layout ) - // Updates the style of current axis with given AxisId + // Updates the style of current geo map with given Id static member UpdateMapById ( id : int, @@ -317,6 +317,24 @@ type Layout() = layout ) + + // Updates the style of current geo map with given Id + static member UpdateMapboxById + ( + id : int, + mapbox : Mapbox + ) = + (fun (layout:Layout) -> + let key = if id < 2 then "mapbox" else sprintf "mapbox%i" id + let mapbox' = + match layout.TryGetTypedValue(key) with + | Some a -> DynObj.combine (unbox a) mapbox + | None -> mapbox :> DynamicObj + + mapbox' |> DynObj.setValue layout key + + layout + ) static member setLegend(legend:Legend) = (fun (layout:Layout) -> diff --git a/src/Plotly.NET/Mapbox.fs b/src/Plotly.NET/Mapbox.fs new file mode 100644 index 000000000..1e8a5131c --- /dev/null +++ b/src/Plotly.NET/Mapbox.fs @@ -0,0 +1,69 @@ +namespace Plotly.NET + +/// Determines the style of the map shown in mapbox traces +type Mapbox() = + + inherit DynamicObj () + + /// Initialize a Mapbox object that determines the style of the map shown in geo mapbox + + static member init + ( + ?Domain: Domain, + ?AccessToken: string, + ?Style: StyleParam.MapboxStyle, + ?Center: (float*float), + ?Zoom: float, + ?Bearing: float, + ?Pitch: float, + ?Layers: seq + ) = + Mapbox() + |> Mapbox.style + ( + ?Domain = Domain, + ?AccessToken= AccessToken, + ?Style = Style, + ?Center = Center, + ?Zoom = Zoom, + ?Bearing = Bearing, + ?Pitch = Pitch, + ?Layers = Layers + ) + + /// Create a function that applies the given style parameters to a Mapbox object. + + static member style + ( + ?Domain: Domain, + ?AccessToken: string, + ?Style: StyleParam.MapboxStyle, + ?Center: (float*float), + ?Zoom: float, + ?Bearing: float, + ?Pitch: float, + ?Layers: seq + + ) = + (fun (mapBox:Mapbox) -> + + Domain |> DynObj.setValueOpt mapBox "domain" + AccessToken |> DynObj.setValueOpt mapBox "accesstoken" + Style |> DynObj.setValueOptBy mapBox "style" StyleParam.MapboxStyle.convert + + Center + |> Option.map (fun (lon,lat) -> + let t = DynamicObj() + t?lon <- lon + t?lat <- lat + t + ) + |> DynObj.setValueOpt mapBox "center" + + Zoom |> DynObj.setValueOpt mapBox "zoom" + Bearing |> DynObj.setValueOpt mapBox "bearing" + Pitch |> DynObj.setValueOpt mapBox "pitch" + Layers |> DynObj.setValueOpt mapBox "layers" + + mapBox + ) diff --git a/src/Plotly.NET/MapboxLayer.fs b/src/Plotly.NET/MapboxLayer.fs new file mode 100644 index 000000000..c5bb66747 --- /dev/null +++ b/src/Plotly.NET/MapboxLayer.fs @@ -0,0 +1,114 @@ +namespace Plotly.NET + +open System + +/// +type MapboxLayer() = + + inherit DynamicObj () + + /// Initialize a MapboxLayer object + + static member init + ( + ?Visible: bool, + ?SourceType: StyleParam.MapboxLayerSourceType, + ?Source: #IConvertible, + ?SourceLayer: string, + ?SourceAttribution: string, + ?Type: StyleParam.MapboxLayerType, + ?Coordinates:seq<#IConvertible*#IConvertible>, + ?Below: string, + ?Color: string, + ?Opacity: float, + ?MinZoom:float, + ?MaxZoom:float, + ?CircleRadius: float, + ?Line:Line, + ?FillOutlineColor:string, + ?Symbol:MapboxLayerSymbol, + ?Name: string + ) = + MapboxLayer() + |> MapboxLayer.style + ( + ?Visible = Visible , + ?SourceType = SourceType , + ?Source = Source , + ?SourceLayer = SourceLayer , + ?SourceAttribution = SourceAttribution, + ?Type = Type , + ?Coordinates = Coordinates , + ?Below = Below , + ?Color = Color , + ?Opacity = Opacity , + ?MinZoom = MinZoom , + ?MaxZoom = MaxZoom , + ?CircleRadius = CircleRadius , + ?Line = Line , + ?FillOutlineColor = FillOutlineColor , + ?Symbol = Symbol , + ?Name = Name + ) + + /// Create a function that applies the given style parameters to a MapboxLayer object. + + static member style + ( + ?Visible: bool, + ?SourceType: StyleParam.MapboxLayerSourceType, + ?Source: #IConvertible, + ?SourceLayer: string, + ?SourceAttribution: string, + ?Type: StyleParam.MapboxLayerType, + ?Coordinates:seq<#IConvertible*#IConvertible>, + ?Below: string, + ?Color: string, + ?Opacity: float, + ?MinZoom:float, + ?MaxZoom:float, + ?CircleRadius: float, + ?Line:Line, + ?FillOutlineColor:string, + ?Symbol:MapboxLayerSymbol, + ?Name: string + + ) = + (fun (mapBoxLayer:MapboxLayer) -> + + Visible |> DynObj.setValueOpt mapBoxLayer "visible" + SourceType |> DynObj.setValueOptBy mapBoxLayer "sourcetype" StyleParam.MapboxLayerSourceType.convert + Source |> DynObj.setValueOpt mapBoxLayer "source" + SourceLayer |> DynObj.setValueOpt mapBoxLayer "sourcelayer" + SourceAttribution|> DynObj.setValueOpt mapBoxLayer "sourceattribution" + Type |> DynObj.setValueOptBy mapBoxLayer "type" StyleParam.MapboxLayerType.convert + Coordinates |> DynObj.setValueOpt mapBoxLayer "coordinates" + Below |> DynObj.setValueOpt mapBoxLayer "below" + Color |> DynObj.setValueOpt mapBoxLayer "color" + Opacity |> DynObj.setValueOpt mapBoxLayer "opacity" + MinZoom |> DynObj.setValueOpt mapBoxLayer "minzoom" + MaxZoom |> DynObj.setValueOpt mapBoxLayer "maxzoom" + + CircleRadius + |> Option.map(fun r -> + let circle = DynamicObj() + circle?radius <- r + circle + ) + |> DynObj.setValueOpt mapBoxLayer "circle" + + Line |> DynObj.setValueOpt mapBoxLayer "line" + + FillOutlineColor + |> Option.map(fun c -> + let fill = DynamicObj() + fill?outlinecolor <- c + fill + ) + |> DynObj.setValueOpt mapBoxLayer "fill" + + Symbol |> DynObj.setValueOpt mapBoxLayer "symbol" + Name |> DynObj.setValueOpt mapBoxLayer "name" + + mapBoxLayer + ) diff --git a/src/Plotly.NET/MapboxLayerSymbol.fs b/src/Plotly.NET/MapboxLayerSymbol.fs new file mode 100644 index 000000000..4778a876e --- /dev/null +++ b/src/Plotly.NET/MapboxLayerSymbol.fs @@ -0,0 +1,55 @@ +namespace Plotly.NET + +open System + +/// +type MapboxLayerSymbol() = + + inherit DynamicObj () + + /// Initialize a MapboxLayer object + + static member init + ( + ?Icon: string, + ?IconSize:float, + ?Text: string, + ?Placement: StyleParam.MapboxLayerSymbolPlacement, + ?TextFont: Font, + ?TextPosition: StyleParam.TextPosition + ) = + MapboxLayerSymbol() + |> MapboxLayerSymbol.style + ( + ?Icon = Icon , + ?IconSize = IconSize , + ?Text = Text , + ?Placement = Placement , + ?TextFont = TextFont , + ?TextPosition = TextPosition + ) + + /// Create a function that applies the given style parameters to a MapboxLayer object. + + static member style + ( + ?Icon: string, + ?IconSize:float, + ?Text: string, + ?Placement: StyleParam.MapboxLayerSymbolPlacement, + ?TextFont: Font, + ?TextPosition: StyleParam.TextPosition + + ) = + (fun (mapBoxLayerSymbol:MapboxLayerSymbol) -> + + Icon |> DynObj.setValueOpt mapBoxLayerSymbol "icon" + IconSize |> DynObj.setValueOpt mapBoxLayerSymbol "iconsize" + Text |> DynObj.setValueOpt mapBoxLayerSymbol "text" + Placement |> DynObj.setValueOptBy mapBoxLayerSymbol "placement" StyleParam.MapboxLayerSymbolPlacement.convert + TextFont |> DynObj.setValueOpt mapBoxLayerSymbol "textfont" + TextPosition|> DynObj.setValueOptBy mapBoxLayerSymbol "textposition" StyleParam.TextPosition.convert + + + mapBoxLayerSymbol + ) diff --git a/src/Plotly.NET/Playground.fsx b/src/Plotly.NET/Playground.fsx index 4d0a22310..559f71db4 100644 --- a/src/Plotly.NET/Playground.fsx +++ b/src/Plotly.NET/Playground.fsx @@ -36,6 +36,9 @@ #load "Trace3d.fs" #load "GeoProjection.fs" #load "Geo.fs" +#load "MapboxLayerSymbol.fs" +#load "MapboxLayer.fs" +#load "Mapbox.fs" #load "LayoutGrid.fs" #load "Annotation.fs" #load "Layout.fs" @@ -60,6 +63,68 @@ open System.IO open Deedle open FSharpAux +let dataDensityMapbox = + Http.RequestString "https://raw.githubusercontent.com/plotly/datasets/master/earthquakes-23k.csv" + |> fun d -> Frame.ReadCsvString(d,true,separators=",") + +dataDensityMapbox.Print() + +let lonDensity = dataDensityMapbox.["Longitude"] |> Series.values +let latDensity = dataDensityMapbox.["Latitude"] |> Series.values +let magnitudes = dataDensityMapbox.["Magnitude"] |> Series.values + +Chart.DensityMapbox( + lonDensity, + latDensity, + Z = magnitudes, + Radius=8., + Colorscale=StyleParam.Colorscale.Viridis +) +|> Chart.withMapbox( + Mapbox.init( + Style = StyleParam.MapboxStyle.StamenTerrain, + Center = (60.,30.) + ) +) +|> Chart.Show + + +let dataMapbox = + let dataString = Http.RequestString "https://raw.githubusercontent.com/plotly/datasets/master/us-cities-top-1k.csv" + let byteArray = Encoding.UTF8.GetBytes(dataString) + use stream = new MemoryStream(byteArray) + Frame.ReadCsv(stream,true,separators=",",schema="City=string,State=string,Population=int,lat=float,lon=float") + +dataMapbox.Print() + +let lon: float [] = + dataMapbox + |> Frame.getCol "lon" + |> Series.values + |> Array.ofSeq + +let lat: float [] = + dataMapbox + |> Frame.getCol "lat" + |> Series.values + |> Array.ofSeq + +Chart.LineMapbox( + longitudes=lon, + latitudes=lat, + ShowMarkers=true, + Name="soos" +) +|> Chart.withMapbox( + Mapbox.init( + Style = StyleParam.MapboxStyle.OpenStreetMap, + Center = (-97.61142,38.84028) + ) +) +|> Chart.withSize(1000.,1000.) +|> Chart.withTitle "lol?" +|> Chart.Show + Chart.Column( keysvalues= [ "second",3 @@ -92,9 +157,7 @@ let geoJson = 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") + Frame.ReadCsvString(dataString,true,separators=",",schema="fips=string,unemp=float") let locations: string [] = data @@ -108,6 +171,17 @@ let z: int [] = |> Series.values |> Array.ofSeq +Chart.ChoroplethMapbox( + locations = locations, + z = z, + geoJson = geoJson, + FeatureIdKey="id" +) +|> Chart.withMapbox( + Mapbox.init(Style=StyleParam.MapboxStyle.OpenStreetMap) +) +|> Chart.Show + Chart.ChoroplethMap( locations = locations, z = z, @@ -327,7 +401,7 @@ Chart.ScatterGeo( |> Chart.Show //test new withMapStyle function -let locations,z = +let locations2,z2 = [("Belarus",17.5); ("Moldova",16.8);("Lithuania",15.4);("Russia",15.1); ("Romania",14.4);("Ukraine",13.9);("Andorra",13.8);("Hungary",13.3); ("Czech Republic",13.);("Slovakia",13.);("Portugal",12.9);("Serbia",12.6); @@ -379,7 +453,7 @@ let locations,z = // Pure alcohol consumption among adults (age 15+) in 2010 -Chart.ChoroplethMap(locations,z,Locationmode=StyleParam.LocationFormat.CountryNames,Colorscale=StyleParam.Colorscale.Electric) +Chart.ChoroplethMap(locations2,z2,Locationmode=StyleParam.LocationFormat.CountryNames,Colorscale=StyleParam.Colorscale.Electric) |> Chart.withMapStyle( Projection=GeoProjection.init(projectionType=StyleParam.GeoProjectionType.Mollweide), ShowLakes=true, diff --git a/src/Plotly.NET/Plotly.NET.fsproj b/src/Plotly.NET/Plotly.NET.fsproj index 0f06135e0..30f3a8f20 100644 --- a/src/Plotly.NET/Plotly.NET.fsproj +++ b/src/Plotly.NET/Plotly.NET.fsproj @@ -66,6 +66,9 @@ + + + diff --git a/src/Plotly.NET/StyleParams.fs b/src/Plotly.NET/StyleParams.fs index f217c7157..73967569a 100644 --- a/src/Plotly.NET/StyleParams.fs +++ b/src/Plotly.NET/StyleParams.fs @@ -207,7 +207,7 @@ module StyleParam = | Custom of seq | RdBu | Earth | Blackbody | YIOrRd | YIGnBu | Bluered | Portland | Electric | Jet | Hot | Greys | Greens | Picnic - + | Rainbow | Viridis | Cividis static member convert = function | Custom (cScale) -> cScale |> Seq.map (fun (v,color) -> [|box v;box color|]) @@ -224,7 +224,10 @@ module StyleParam = | Hot -> box "Hot" | Greys -> box "Greys" | Greens -> box "Greens" - | Picnic -> box "Picnic" + | Picnic -> box "Picnic" + | Rainbow -> box "Rainbow" + | Viridis -> box "Viridis" + | Cividis -> box "Cividis" /// Specifies the ordering logic for the case of categorical variables. By default, plotly uses "trace", which specifies the order that is present in the data supplied. /// Set `categoryorder` to "category ascending" or "category descending" if order should be determined by the alphanumerical order of the category names. @@ -809,6 +812,103 @@ module StyleParam = else cmode + /// Defines the map layers that are rendered by default below the trace layers defined in `data`, which are themselves by default rendered below the layers defined in `layout.mapbox.layers`. + /// These layers can be defined either explicitly as a Mapbox Style object which can contain multiple layer definitions that load data from any public or private Tile Map Service (TMS or XYZ) or Web Map Service (WMS) or implicitly by using one of the built-in style objects which use WMSes which do not require any access tokens, + /// or by using a default Mapbox style or custom Mapbox style URL, both of which require a Mapbox access token Note that Mapbox access token can be set in the `accesstoken` attribute or in the `mapboxAccessToken` config option. + /// Mapbox Style objects are of the form described in the Mapbox GL JS documentation available at https://docs.mapbox.com/mapbox-gl-js/style-spec The built-in plotly.js styles objects are: open-street-map, white-bg, carto-positron, carto-darkmatter, stamen-terrain, stamen-toner, stamen-watercolor + /// The built-in Mapbox styles are: basic, streets, outdoors, light, dark, satellite, satellite-streets Mapbox style URLs are of the form: mapbox://mapbox.mapbox-- + [] + type MapboxStyle = + // plotly presets + | OpenStreetMap + | WhiteBG + | CartoPositron + | CartoDarkmatter + | StamenTerrain + | StamenToner + | StamenWatercolor + + // Mapbox presets + | MapboxBasic + | MapboxStreets + | MapboxOutdoors + | MapboxLight + | MapboxDark + | MapboxSatellite + | MapboxSatelliteStreets + + //Custom + | Custom of string + + static member toString = function + + | OpenStreetMap -> "open-street-map" + | WhiteBG -> "white-bg" + | CartoPositron -> "carto-positron" + | CartoDarkmatter -> "carto-darkmatter" + | StamenTerrain -> "stamen-terrain" + | StamenToner -> "stamen-toner" + | StamenWatercolor -> "stamen-watercolor" + + | MapboxBasic -> "basic" + | MapboxStreets -> "streets" + | MapboxOutdoors -> "outdoors" + | MapboxLight -> "light" + | MapboxDark -> "dark" + | MapboxSatellite -> "satellite" + | MapboxSatelliteStreets -> "satellite-streets" + + | Custom s -> s + + static member convert = MapboxStyle.toString >> box + + [] + type MapboxLayerSourceType = + | GeoJson + | Vector + | Raster + | Image + + static member toString = function + | GeoJson -> "geojson" + | Vector -> "vector" + | Raster -> "raster" + | Image -> "image" + + static member convert = MapboxLayerSourceType.toString >> box + + [] + type MapboxLayerType = + | Circle + | Line + | Fill + | Symbol + | Raster + + static member toString = function + | Circle -> "circle" + | Line -> "line" + | Fill -> "fill" + | Symbol -> "symbol" + | Raster -> "raster" + + static member convert = MapboxLayerType.toString >> box + + + [] + type MapboxLayerSymbolPlacement = + | Point + | Line + | LineCenter + + static member toString = function + | Point -> "point" + | Line -> "line" + | LineCenter -> "line-center" + + static member convert = MapboxLayerSymbolPlacement.toString >> box + + //-------------------------- // #N# //-------------------------- diff --git a/src/Plotly.NET/Trace.fs b/src/Plotly.NET/Trace.fs index a1dcb8ed1..115817e19 100644 --- a/src/Plotly.NET/Trace.fs +++ b/src/Plotly.NET/Trace.fs @@ -374,6 +374,9 @@ module Trace = ) + + + /// Sets the given domain on a Trace object. static member SetDomain ( @@ -1167,15 +1170,16 @@ module Trace = ?Locations : seq, ?Z : seq<#IConvertible>, ?Text : seq<#IConvertible>, - ?Locationmode , + ?Locationmode : StyleParam.LocationFormat, ?Autocolorscale : bool, - ?Colorscale, - ?Colorbar, + ?Colorscale : StyleParam.Colorscale, + ?Colorbar : Colorbar, ?Marker : Marker, ?GeoJson, - ?FeatureIdKey: string, - ?Zmin, - ?Zmax + ?FeatureIdKey : string, + ?Zmin : float, + ?Zmid : float, + ?Zmax : float ) = @@ -1193,6 +1197,7 @@ module Trace = GeoJson |> DynObj.setValueOpt choropleth "geojson" FeatureIdKey |> DynObj.setValueOpt choropleth "featureidkey" Zmin |> DynObj.setValueOpt choropleth "zmin" + Zmid |> DynObj.setValueOpt choropleth "zmid" Zmax |> DynObj.setValueOpt choropleth "zmax" // out -> @@ -1570,4 +1575,100 @@ module Trace = trace + ) + + static member ScatterMapbox + ( + mode : StyleParam.Mode, + ?Longitudes : #IConvertible seq, + ?Latitudes : #IConvertible seq, + ?Below : string, + ?Connectgaps: bool, + ?Fill : StyleParam.Fill, + ?Fillcolor : string + ) = + (fun (trace:('T :> Trace)) -> + + mode |> StyleParam.Mode.convert |> DynObj.setValue trace "mode" + Longitudes |> DynObj.setValueOpt trace "lon" + Latitudes |> DynObj.setValueOpt trace "lat" + Below |> DynObj.setValueOpt trace "below" + Connectgaps |> DynObj.setValueOpt trace "connectgaps" + Fill |> DynObj.setValueOptBy trace "fill" StyleParam.Fill.convert + Fillcolor |> DynObj.setValueOpt trace "fillcolor" + + trace + ) + + static member ChoroplethMapbox + ( + ?Z : seq<#IConvertible>, + ?GeoJson, + ?FeatureIdKey : string, + ?Locations : seq<#IConvertible>, + ?Text : seq<#IConvertible>, + ?Below : string, + ?Colorscale : StyleParam.Colorscale, + ?Colorbar : Colorbar, + ?Showscale : bool, + ?ZAuto : bool, + ?ZMin : float, + ?ZMid : float, + ?ZMax : float + ) = + (fun (trace:('T :> Trace)) -> + + Z |> DynObj.setValueOpt trace "z" + GeoJson |> DynObj.setValueOpt trace "geojson" + FeatureIdKey|> DynObj.setValueOpt trace "featureidkey" + Locations |> DynObj.setValueOpt trace "locations" + Text |> DynObj.setValueOpt trace "text" + Below |> DynObj.setValueOpt trace "below" + Colorscale |> DynObj.setValueOptBy trace "colorscale" StyleParam.Colorscale.convert + Colorbar |> DynObj.setValueOpt trace "colorbar" + Showscale |> DynObj.setValueOpt trace "showscale" + ZAuto |> DynObj.setValueOpt trace "zauto" + ZMin |> DynObj.setValueOpt trace "zmin" + ZMid |> DynObj.setValueOpt trace "zmid" + ZMax |> DynObj.setValueOpt trace "zmax" + + trace + ) + + static member DensityMapbox + ( + ?Z : seq<#IConvertible>, + ?Radius : float, + ?Longitudes : #IConvertible seq, + ?Latitudes : #IConvertible seq, + ?Opacity : float, + ?Text : seq<#IConvertible>, + ?Below : string, + ?Colorscale : StyleParam.Colorscale, + ?Colorbar : Colorbar, + ?Showscale : bool, + ?ZAuto : bool, + ?ZMin : float, + ?ZMid : float, + ?ZMax : float + + ) = + (fun (trace:('T :> Trace)) -> + + Z |> DynObj.setValueOpt trace "z" + Radius |> DynObj.setValueOpt trace "radius" + Longitudes |> DynObj.setValueOpt trace "lon" + Latitudes |> DynObj.setValueOpt trace "lat" + Opacity |> DynObj.setValueOpt trace "opacity" + Text |> DynObj.setValueOpt trace "text" + Below |> DynObj.setValueOpt trace "below" + Colorscale |> DynObj.setValueOptBy trace "colorscale" StyleParam.Colorscale.convert + Colorbar |> DynObj.setValueOpt trace "colorbar" + Showscale |> DynObj.setValueOpt trace "showscale" + ZAuto |> DynObj.setValueOpt trace "zauto" + ZMin |> DynObj.setValueOpt trace "zmin" + ZMid |> DynObj.setValueOpt trace "zmid" + ZMax |> DynObj.setValueOpt trace "zmax" + + trace ) \ No newline at end of file