From f81a92c041d5eb6f31d427cd206a5e0d69e3afd6 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Thu, 24 Jun 2021 15:20:31 +0200 Subject: [PATCH 01/13] Add MapBox related layout options and types --- src/Plotly.NET/ChartExtensions.fs | 11 +++ src/Plotly.NET/Layout.fs | 20 ++++- src/Plotly.NET/MapBox.fs | 69 +++++++++++++++++ src/Plotly.NET/MapBoxLayer.fs | 114 ++++++++++++++++++++++++++++ src/Plotly.NET/MapBoxLayerSymbol.fs | 55 ++++++++++++++ src/Plotly.NET/Plotly.NET.fsproj | 3 + src/Plotly.NET/StyleParams.fs | 97 +++++++++++++++++++++++ 7 files changed, 368 insertions(+), 1 deletion(-) create mode 100644 src/Plotly.NET/MapBox.fs create mode 100644 src/Plotly.NET/MapBoxLayer.fs create mode 100644 src/Plotly.NET/MapBoxLayerSymbol.fs diff --git a/src/Plotly.NET/ChartExtensions.fs b/src/Plotly.NET/ChartExtensions.fs index 1d26c64e3..9426fca62 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/Layout.fs b/src/Plotly.NET/Layout.fs index fdd7e14fe..bc3d38702 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..e1cc3faec --- /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 + ) \ No newline at end of file diff --git a/src/Plotly.NET/MapBoxLayer.fs b/src/Plotly.NET/MapBoxLayer.fs new file mode 100644 index 000000000..0ab27be85 --- /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 + ) \ No newline at end of file diff --git a/src/Plotly.NET/MapBoxLayerSymbol.fs b/src/Plotly.NET/MapBoxLayerSymbol.fs new file mode 100644 index 000000000..ab8321ce9 --- /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 + ) \ No newline at end of file diff --git a/src/Plotly.NET/Plotly.NET.fsproj b/src/Plotly.NET/Plotly.NET.fsproj index 0f06135e0..015b5e8a7 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..58d66beb5 100644 --- a/src/Plotly.NET/StyleParams.fs +++ b/src/Plotly.NET/StyleParams.fs @@ -809,6 +809,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# //-------------------------- From 051a189c767fc336b759fef332f0313dcccb9bc9 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Thu, 24 Jun 2021 15:21:56 +0200 Subject: [PATCH 02/13] Add GenericChart withMapBox extension --- src/Plotly.NET/GenericChartExtensions.fs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Plotly.NET/GenericChartExtensions.fs b/src/Plotly.NET/GenericChartExtensions.fs index 1118459ed..8177c0a63 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) /// From 85df2741e0f2cb9ab27ed8569a06da2fabe03b13 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Thu, 24 Jun 2021 17:15:25 +0200 Subject: [PATCH 03/13] #42: Add Chart.ScatterMapBox and derived Charts --- src/Plotly.NET/Chart.fs | 357 +++++++++++++++++++++++++++++++++- src/Plotly.NET/Playground.fsx | 43 +++- src/Plotly.NET/StyleParams.fs | 6 +- src/Plotly.NET/Trace.fs | 26 +++ 4 files changed, 426 insertions(+), 6 deletions(-) diff --git a/src/Plotly.NET/Chart.fs b/src/Plotly.NET/Chart.fs index c6416910c..859856fb3 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,358 @@ 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 + ) diff --git a/src/Plotly.NET/Playground.fsx b/src/Plotly.NET/Playground.fsx index 4d0a22310..aa1ca3a0a 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,42 @@ open System.IO open Deedle open FSharpAux +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 @@ -327,7 +366,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 +418,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/StyleParams.fs b/src/Plotly.NET/StyleParams.fs index 58d66beb5..b43ba64c7 100644 --- a/src/Plotly.NET/StyleParams.fs +++ b/src/Plotly.NET/StyleParams.fs @@ -899,9 +899,9 @@ module StyleParam = | LineCenter static member toString = function - | Point -> "point" - | Line -> "line" - | LineCenter -> "line-center" + | Point -> "point" + | Line -> "line" + | LineCenter -> "line-center" static member convert = MapBoxLayerSymbolPlacement.toString >> box diff --git a/src/Plotly.NET/Trace.fs b/src/Plotly.NET/Trace.fs index a1dcb8ed1..a995fc5ca 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 ( @@ -1570,4 +1573,27 @@ module Trace = trace + ) + + static member ScatterMapBox + ( + mode : StyleParam.Mode, + ?Longitudes : #IConvertible seq, + ?Latitudes : #IConvertible seq, + ?Below: string, + ?Connectgaps : bool, + ?Fill : StyleParam.Fill, + ?Fillcolor + ) = + (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 ) \ No newline at end of file From 2edfe1b81f45971e7d3106b739aceedefee7a0b0 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Thu, 24 Jun 2021 18:22:10 +0200 Subject: [PATCH 04/13] Update map based docs: split between mapbox/geo, add more info about both --- Plotly.NET.sln | 24 ++-- docs/5_0_geo-vs-mapbox.fsx | 131 ++++++++++++++++++ docs/5_1_geo-plots.fsx | 32 +++++ ...ropleth-map.fsx => 5_2_choropleth-map.fsx} | 4 +- docs/6_0_geo-vs-mapbox.fsx | 127 +++++++++++++++++ docs/6_1_mapbox-plots.fsx | 32 +++++ docs/6_2_choropleth-mapbox.fsx | 32 +++++ docs/6_3_density-mapbox.fsx | 33 +++++ ..._0_candlestick.fsx => 7_0_candlestick.fsx} | 2 +- docs/{6_1_funnel.fsx => 7_1_funnel.fsx} | 0 ..._2_funnel_area.fsx => 7_2_funnel_area.fsx} | 0 ..._polar-charts.fsx => 8_0_polar-charts.fsx} | 0 ...ose-charts.fsx => 8_1_windrose-charts.fsx} | 0 ...gories.fsx => 9_0_parallel-categories.fsx} | 0 ...lel-coords.fsx => 9_1_parallel-coords.fsx} | 0 docs/{8_2_sankey.fsx => 9_2_sankey.fsx} | 0 docs/content/fsdocs-custom.css | 7 +- 17 files changed, 410 insertions(+), 14 deletions(-) create mode 100644 docs/5_0_geo-vs-mapbox.fsx create mode 100644 docs/5_1_geo-plots.fsx rename docs/{5_0_choropleth-map.fsx => 5_2_choropleth-map.fsx} (99%) create mode 100644 docs/6_0_geo-vs-mapbox.fsx create mode 100644 docs/6_1_mapbox-plots.fsx create mode 100644 docs/6_2_choropleth-mapbox.fsx create mode 100644 docs/6_3_density-mapbox.fsx rename docs/{6_0_candlestick.fsx => 7_0_candlestick.fsx} (99%) rename docs/{6_1_funnel.fsx => 7_1_funnel.fsx} (100%) rename docs/{6_2_funnel_area.fsx => 7_2_funnel_area.fsx} (100%) rename docs/{7_0_polar-charts.fsx => 8_0_polar-charts.fsx} (100%) rename docs/{7_1_windrose-charts.fsx => 8_1_windrose-charts.fsx} (100%) rename docs/{8_0_parallel-categories.fsx => 9_0_parallel-categories.fsx} (100%) rename docs/{8_1_parallel-coords.fsx => 9_1_parallel-coords.fsx} (100%) rename docs/{8_2_sankey.fsx => 9_2_sankey.fsx} (100%) 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..52cba88c2 --- /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..ed720b843 --- /dev/null +++ b/docs/5_1_geo-plots.fsx @@ -0,0 +1,32 @@ +(** +--- +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#. + +*More coming soonTM* +*) diff --git a/docs/5_0_choropleth-map.fsx b/docs/5_2_choropleth-map.fsx similarity index 99% rename from docs/5_0_choropleth-map.fsx rename to docs/5_2_choropleth-map.fsx index 4dd1b33ee..e48aa8cfc 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 --- *) diff --git a/docs/6_0_geo-vs-mapbox.fsx b/docs/6_0_geo-vs-mapbox.fsx new file mode 100644 index 000000000..26306fdf3 --- /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..a10cfab30 --- /dev/null +++ b/docs/6_1_mapbox-plots.fsx @@ -0,0 +1,32 @@ +(** +--- +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#. + +*More coming soonTM* +*) diff --git a/docs/6_2_choropleth-mapbox.fsx b/docs/6_2_choropleth-mapbox.fsx new file mode 100644 index 000000000..1d92f6817 --- /dev/null +++ b/docs/6_2_choropleth-mapbox.fsx @@ -0,0 +1,32 @@ +(** +--- +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#. + +*More coming soonTM* +*) diff --git a/docs/6_3_density-mapbox.fsx b/docs/6_3_density-mapbox.fsx new file mode 100644 index 000000000..82d05bb90 --- /dev/null +++ b/docs/6_3_density-mapbox.fsx @@ -0,0 +1,33 @@ +(** +--- +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#. + +*More coming soonTM* + +*) \ 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, From eb9e234e63c7158f2006fef802579b93a326244f Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Fri, 25 Jun 2021 11:41:10 +0200 Subject: [PATCH 05/13] Rename MapBox -> Mapbox --- docs/5_0_geo-vs-mapbox.fsx | 2 +- docs/6_0_geo-vs-mapbox.fsx | 42 ++++++++-------- docs/6_2_choropleth-mapbox.fsx | 4 +- docs/6_3_density-mapbox.fsx | 6 +-- src/Plotly.NET/Chart.fs | 64 ++++++++++++------------ src/Plotly.NET/ChartExtensions.fs | 6 +-- src/Plotly.NET/GenericChartExtensions.fs | 6 +-- src/Plotly.NET/Layout.fs | 6 +-- src/Plotly.NET/MapBox.fs | 22 ++++---- src/Plotly.NET/MapBoxLayer.fs | 28 +++++------ src/Plotly.NET/MapBoxLayerSymbol.fs | 18 +++---- src/Plotly.NET/Playground.fsx | 22 ++++---- src/Plotly.NET/Plotly.NET.fsproj | 6 +-- src/Plotly.NET/StyleParams.fs | 44 ++++++++-------- src/Plotly.NET/Trace.fs | 2 +- 15 files changed, 139 insertions(+), 139 deletions(-) diff --git a/docs/5_0_geo-vs-mapbox.fsx b/docs/5_0_geo-vs-mapbox.fsx index 52cba88c2..87ca09947 100644 --- a/docs/5_0_geo-vs-mapbox.fsx +++ b/docs/5_0_geo-vs-mapbox.fsx @@ -30,7 +30,7 @@ index: 1 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`, +- **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 diff --git a/docs/6_0_geo-vs-mapbox.fsx b/docs/6_0_geo-vs-mapbox.fsx index 26306fdf3..83b99891b 100644 --- a/docs/6_0_geo-vs-mapbox.fsx +++ b/docs/6_0_geo-vs-mapbox.fsx @@ -30,7 +30,7 @@ index: 1 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`, +- **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 @@ -42,23 +42,23 @@ _This page documents Mapbox tile-based maps, and the [Geo map documentation]({{r 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 `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). +- 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: +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. +// a simple Mapbox with a OpenStreetMap base layer. let mb = - MapBox.init( - Style = StyleParam.MapBoxStyle.OpenStreetMap + 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 + Chart.PointMapbox([],[]) // deliberately empty chart to show the base map only + |> Chart.withMapbox mb // add the mapBox (*** condition: ipynb ***) #if IPYNB @@ -82,8 +82,8 @@ This token should be provided via the `AccessToken` property: *) let mbWithToken = - MapBox.init( - Style = StyleParam.MapBoxStyle.OpenStreetMap, + Mapbox.init( + Style = StyleParam.MapboxStyle.OpenStreetMap, AccessToken = "your_token_here" ) @@ -96,15 +96,15 @@ If your base map does not use data from the Mapbox service, you do not need to r - `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: +- 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`: +The accepted values for the `style` property of the `Mapbox` object are represented in `StyleParam.MapboxStyle`: *) -type MapBoxStyle = +type MapboxStyle = // plotly presets, no token needed | WhiteBG | OpenStreetMap @@ -115,13 +115,13 @@ type MapBoxStyle = | StamenWatercolor // Mapbox presets, you might need a free token - | MapBoxBasic - | MapBoxStreets - | MapBoxOutdoors - | MapBoxLight - | MapBoxDark - | MapBoxSatellite - | MapBoxSatelliteStreets + | 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_2_choropleth-mapbox.fsx b/docs/6_2_choropleth-mapbox.fsx index 1d92f6817..877c41a02 100644 --- a/docs/6_2_choropleth-mapbox.fsx +++ b/docs/6_2_choropleth-mapbox.fsx @@ -1,6 +1,6 @@ (** --- -title: ChoroplethMapBox +title: ChoroplethMapbox category: Mapbox map charts categoryindex: 7 index: 3 @@ -20,7 +20,7 @@ index: 3 #endif // IPYNB (** -# ChoroplethMapBox +# 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)  diff --git a/docs/6_3_density-mapbox.fsx b/docs/6_3_density-mapbox.fsx index 82d05bb90..436710483 100644 --- a/docs/6_3_density-mapbox.fsx +++ b/docs/6_3_density-mapbox.fsx @@ -1,6 +1,6 @@ (** --- -title: DensityMapBox charts +title: DensityMapbox charts category: Mapbox map charts categoryindex: 7 index: 4 @@ -20,13 +20,13 @@ index: 4 #endif // IPYNB (** -# DensityMapBox charts +# 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#. +*Summary:* This example shows how to create DensityMapbox charts in F#. *More coming soonTM* diff --git a/src/Plotly.NET/Chart.fs b/src/Plotly.NET/Chart.fs index 859856fb3..fc6e0c25e 100644 --- a/src/Plotly.NET/Chart.fs +++ b/src/Plotly.NET/Chart.fs @@ -2825,13 +2825,13 @@ type Chart = |> GenericChart.ofTraceObject /// - /// Creates a ScatterMapBox chart, where data is visualized by (longitude,latitude) pairs on a geographic map using mapbox. + /// 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. + /// Customize the mapbox layers, style, etc. by using Chart.withMapbox. /// - /// You might need a MapBox token, which you can also configure with 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 + /// 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). @@ -2848,7 +2848,7 @@ type Chart = /// 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, + static member ScatterMapbox(longitudes, latitudes, mode, [] ?Name , [] ?ShowLegend , [] ?Color , @@ -2864,7 +2864,7 @@ type Chart = ) = Trace.initScatterMapbox( - TraceStyle.ScatterMapBox( + TraceStyle.ScatterMapbox( mode = mode , Longitudes = longitudes , Latitudes = latitudes , @@ -2881,13 +2881,13 @@ type Chart = |> GenericChart.ofTraceObject /// - /// Creates a ScatterMapBox chart, where data is visualized by (longitude,latitude) pairs on a geographic map using mapbox. + /// 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. + /// Customize the mapbox layers, style, etc. by using Chart.withMapbox. /// - /// You might need a MapBox token, which you can also configure with 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 + /// 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. @@ -2903,7 +2903,7 @@ type Chart = /// 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, + static member ScatterMapbox(lonlat, mode, [] ?Name , [] ?ShowLegend , [] ?Color , @@ -2920,7 +2920,7 @@ type Chart = let longitudes, latitudes = Seq.unzip lonlat - Chart.ScatterMapBox( + Chart.ScatterMapbox( longitudes, latitudes, mode, @@ -2939,11 +2939,11 @@ type Chart = ) /// - /// Creates a PointMapBox chart, where data is visualized by (longitude,latitude) pairs as Points on a geographic map using mapbox. + /// 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. + /// Customize the mapbox layers, style, etc. by using Chart.withMapbox. /// - /// You might need a MapBox token, which you can also configure with 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). @@ -2959,7 +2959,7 @@ type Chart = /// 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, + static member PointMapbox(longitudes,latitudes, [] ?Name , [] ?ShowLegend , [] ?Color , @@ -2976,7 +2976,7 @@ type Chart = let changeMode = StyleParam.ModeUtils.showText (TextPosition.IsSome || TextFont.IsSome) - Chart.ScatterMapBox( + Chart.ScatterMapbox( longitudes, latitudes, mode = changeMode StyleParam.Mode.Markers , @@ -2995,11 +2995,11 @@ type Chart = ) /// - /// Creates a PointMapBox chart, where data is visualized by (longitude,latitude) pairs as Points on a geographic map using mapbox. + /// 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. + /// Customize the mapbox layers, style, etc. by using Chart.withMapbox. /// - /// You might need a MapBox token, which you can also configure with 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. @@ -3014,7 +3014,7 @@ type Chart = /// 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, + static member PointMapbox(lonlat, [] ?Name , [] ?ShowLegend , [] ?Color , @@ -3032,7 +3032,7 @@ type Chart = let changeMode = StyleParam.ModeUtils.showText (TextPosition.IsSome || TextFont.IsSome) let longitudes, latitudes = Seq.unzip lonlat - Chart.ScatterMapBox( + Chart.ScatterMapbox( longitudes, latitudes, mode = changeMode StyleParam.Mode.Markers , @@ -3050,11 +3050,11 @@ type Chart = ?Fillcolor = Fillcolor ) /// - /// Creates a LineMapBox chart, where data is visualized by (longitude,latitude) pairs connected by a line on a geographic map using mapbox. + /// 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. + /// Customize the mapbox layers, style, etc. by using Chart.withMapbox. /// - /// You might need a MapBox token, which you can also configure with 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). @@ -3071,7 +3071,7 @@ type Chart = /// 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, + static member LineMapbox(longitudes,latitudes, [] ?Name , [] ?ShowLegend , [] ?ShowMarkers , @@ -3096,7 +3096,7 @@ type Chart = StyleParam.ModeUtils.showText (TextPosition.IsSome || TextFont.IsSome) >> StyleParam.ModeUtils.showMarker (isShowMarker) - Chart.ScatterMapBox( + Chart.ScatterMapbox( longitudes, latitudes, mode = changeMode StyleParam.Mode.Lines , @@ -3115,11 +3115,11 @@ type Chart = ) /// - /// Creates a LineMapBox chart, where data is visualized by (longitude,latitude) pairs connected by a line on a geographic map using mapbox. + /// 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. + /// Customize the mapbox layers, style, etc. by using Chart.withMapbox. /// - /// You might need a MapBox token, which you can also configure with 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. @@ -3135,7 +3135,7 @@ type Chart = /// 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, + static member LineMapbox(lonlat, [] ?Name , [] ?ShowLegend , [] ?ShowMarkers , @@ -3160,7 +3160,7 @@ type Chart = >> StyleParam.ModeUtils.showMarker (isShowMarker) let longitudes, latitudes = Seq.unzip lonlat - Chart.ScatterMapBox( + Chart.ScatterMapbox( longitudes, latitudes, mode = changeMode StyleParam.Mode.Lines , diff --git a/src/Plotly.NET/ChartExtensions.fs b/src/Plotly.NET/ChartExtensions.fs index 9426fca62..ec75eb741 100644 --- a/src/Plotly.NET/ChartExtensions.fs +++ b/src/Plotly.NET/ChartExtensions.fs @@ -401,13 +401,13 @@ module ChartExtensions = ) /// Sets a mapbox for the given chart (will only work with traces supporting mapboxes, e.g. choroplethmapbox, scattermapbox) - [] - static member withMapBox(mapBox:MapBox,[] ?Id ) = + [] + static member withMapbox(mapBox:Mapbox,[] ?Id ) = (fun (ch:GenericChart) -> let layout = let id = defaultArg Id 1 GenericChart.getLayout ch - |> Layout.UpdateMapBoxById(id,mapBox) + |> Layout.UpdateMapboxById(id,mapBox) GenericChart.setLayout layout ch ) diff --git a/src/Plotly.NET/GenericChartExtensions.fs b/src/Plotly.NET/GenericChartExtensions.fs index 8177c0a63..a20a04630 100644 --- a/src/Plotly.NET/GenericChartExtensions.fs +++ b/src/Plotly.NET/GenericChartExtensions.fs @@ -336,13 +336,13 @@ module GenericChartExtensions = 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 ) = + member this.withMapbox(mapBox:Mapbox,[] ?Id ) = let layout = let id = defaultArg Id 1 GenericChart.getLayout this - |> Layout.UpdateMapBoxById(id,mapBox) + |> Layout.UpdateMapboxById(id,mapBox) GenericChart.setLayout layout this diff --git a/src/Plotly.NET/Layout.fs b/src/Plotly.NET/Layout.fs index bc3d38702..34fe3e0ed 100644 --- a/src/Plotly.NET/Layout.fs +++ b/src/Plotly.NET/Layout.fs @@ -319,15 +319,15 @@ type Layout() = ) // Updates the style of current geo map with given Id - static member UpdateMapBoxById + static member UpdateMapboxById ( id : int, - mapbox : MapBox + mapbox : Mapbox ) = (fun (layout:Layout) -> let key = if id < 2 then "mapbox" else sprintf "mapbox%i" id let mapbox' = - match layout.TryGetTypedValue(key) with + match layout.TryGetTypedValue(key) with | Some a -> DynObj.combine (unbox a) mapbox | None -> mapbox :> DynamicObj diff --git a/src/Plotly.NET/MapBox.fs b/src/Plotly.NET/MapBox.fs index e1cc3faec..26c4dc9c1 100644 --- a/src/Plotly.NET/MapBox.fs +++ b/src/Plotly.NET/MapBox.fs @@ -1,25 +1,25 @@ namespace Plotly.NET /// Determines the style of the map shown in mapbox traces -type MapBox() = +type Mapbox() = inherit DynamicObj () - /// Initialize a MapBox object that determines the style of the map shown in geo mapbox + /// 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, + ?Style: StyleParam.MapboxStyle, ?Center: (float*float), ?Zoom: float, ?Bearing: float, ?Pitch: float, - ?Layers: seq + ?Layers: seq ) = - MapBox() - |> MapBox.style + Mapbox() + |> Mapbox.style ( ?Domain = Domain, ?AccessToken= AccessToken, @@ -31,25 +31,25 @@ type MapBox() = ?Layers = Layers ) - /// Create a function that applies the given style parameters to a MapBox object. + /// Create a function that applies the given style parameters to a Mapbox object. static member style ( ?Domain: Domain, ?AccessToken: string, - ?Style: StyleParam.MapBoxStyle, + ?Style: StyleParam.MapboxStyle, ?Center: (float*float), ?Zoom: float, ?Bearing: float, ?Pitch: float, - ?Layers: seq + ?Layers: seq ) = - (fun (mapBox:MapBox) -> + (fun (mapBox:Mapbox) -> Domain |> DynObj.setValueOpt mapBox "domain" AccessToken |> DynObj.setValueOpt mapBox "accesstoken" - Style |> DynObj.setValueOptBy mapBox "style" StyleParam.MapBoxStyle.convert + Style |> DynObj.setValueOptBy mapBox "style" StyleParam.MapboxStyle.convert Center |> Option.map (fun (lon,lat) -> diff --git a/src/Plotly.NET/MapBoxLayer.fs b/src/Plotly.NET/MapBoxLayer.fs index 0ab27be85..117edd168 100644 --- a/src/Plotly.NET/MapBoxLayer.fs +++ b/src/Plotly.NET/MapBoxLayer.fs @@ -3,20 +3,20 @@ open System /// -type MapBoxLayer() = +type MapboxLayer() = inherit DynamicObj () - /// Initialize a MapBoxLayer object + /// Initialize a MapboxLayer object static member init ( ?Visible: bool, - ?SourceType: StyleParam.MapBoxLayerSourceType, + ?SourceType: StyleParam.MapboxLayerSourceType, ?Source: #IConvertible, ?SourceLayer: string, ?SourceAttribution: string, - ?Type: StyleParam.MapBoxLayerType, + ?Type: StyleParam.MapboxLayerType, ?Coordinates:seq<#IConvertible*#IConvertible>, ?Below: string, ?Color: string, @@ -26,11 +26,11 @@ type MapBoxLayer() = ?CircleRadius: float, ?Line:Line, ?FillOutlineColor:string, - ?Symbol:MapBoxLayerSymbol, + ?Symbol:MapboxLayerSymbol, ?Name: string ) = - MapBoxLayer() - |> MapBoxLayer.style + MapboxLayer() + |> MapboxLayer.style ( ?Visible = Visible , ?SourceType = SourceType , @@ -51,16 +51,16 @@ type MapBoxLayer() = ?Name = Name ) - /// Create a function that applies the given style parameters to a MapBoxLayer object. + /// Create a function that applies the given style parameters to a MapboxLayer object. static member style ( ?Visible: bool, - ?SourceType: StyleParam.MapBoxLayerSourceType, + ?SourceType: StyleParam.MapboxLayerSourceType, ?Source: #IConvertible, ?SourceLayer: string, ?SourceAttribution: string, - ?Type: StyleParam.MapBoxLayerType, + ?Type: StyleParam.MapboxLayerType, ?Coordinates:seq<#IConvertible*#IConvertible>, ?Below: string, ?Color: string, @@ -70,18 +70,18 @@ type MapBoxLayer() = ?CircleRadius: float, ?Line:Line, ?FillOutlineColor:string, - ?Symbol:MapBoxLayerSymbol, + ?Symbol:MapboxLayerSymbol, ?Name: string ) = - (fun (mapBoxLayer:MapBoxLayer) -> + (fun (mapBoxLayer:MapboxLayer) -> Visible |> DynObj.setValueOpt mapBoxLayer "visible" - SourceType |> DynObj.setValueOptBy mapBoxLayer "sourcetype" StyleParam.MapBoxLayerSourceType.convert + 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 + Type |> DynObj.setValueOptBy mapBoxLayer "type" StyleParam.MapboxLayerType.convert Coordinates |> DynObj.setValueOpt mapBoxLayer "coordinates" Below |> DynObj.setValueOpt mapBoxLayer "below" Color |> DynObj.setValueOpt mapBoxLayer "color" diff --git a/src/Plotly.NET/MapBoxLayerSymbol.fs b/src/Plotly.NET/MapBoxLayerSymbol.fs index ab8321ce9..59605e9c6 100644 --- a/src/Plotly.NET/MapBoxLayerSymbol.fs +++ b/src/Plotly.NET/MapBoxLayerSymbol.fs @@ -3,23 +3,23 @@ open System /// -type MapBoxLayerSymbol() = +type MapboxLayerSymbol() = inherit DynamicObj () - /// Initialize a MapBoxLayer object + /// Initialize a MapboxLayer object static member init ( ?Icon: string, ?IconSize:float, ?Text: string, - ?Placement: StyleParam.MapBoxLayerSymbolPlacement, + ?Placement: StyleParam.MapboxLayerSymbolPlacement, ?TextFont: Font, ?TextPosition: StyleParam.TextPosition ) = - MapBoxLayerSymbol() - |> MapBoxLayerSymbol.style + MapboxLayerSymbol() + |> MapboxLayerSymbol.style ( ?Icon = Icon , ?IconSize = IconSize , @@ -29,24 +29,24 @@ type MapBoxLayerSymbol() = ?TextPosition = TextPosition ) - /// Create a function that applies the given style parameters to a MapBoxLayer object. + /// 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, + ?Placement: StyleParam.MapboxLayerSymbolPlacement, ?TextFont: Font, ?TextPosition: StyleParam.TextPosition ) = - (fun (mapBoxLayerSymbol:MapBoxLayerSymbol) -> + (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 + Placement |> DynObj.setValueOptBy mapBoxLayerSymbol "placement" StyleParam.MapboxLayerSymbolPlacement.convert TextFont |> DynObj.setValueOpt mapBoxLayerSymbol "textfont" TextPosition|> DynObj.setValueOptBy mapBoxLayerSymbol "textposition" StyleParam.TextPosition.convert diff --git a/src/Plotly.NET/Playground.fsx b/src/Plotly.NET/Playground.fsx index aa1ca3a0a..498afa61e 100644 --- a/src/Plotly.NET/Playground.fsx +++ b/src/Plotly.NET/Playground.fsx @@ -36,9 +36,9 @@ #load "Trace3d.fs" #load "GeoProjection.fs" #load "Geo.fs" -#load "MapBoxLayerSymbol.fs" -#load "MapBoxLayer.fs" -#load "MapBox.fs" +#load "MapboxLayerSymbol.fs" +#load "MapboxLayer.fs" +#load "Mapbox.fs" #load "LayoutGrid.fs" #load "Annotation.fs" #load "Layout.fs" @@ -63,35 +63,35 @@ open System.IO open Deedle open FSharpAux -let dataMapBox = +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() +dataMapbox.Print() let lon: float [] = - dataMapBox + dataMapbox |> Frame.getCol "lon" |> Series.values |> Array.ofSeq let lat: float [] = - dataMapBox + dataMapbox |> Frame.getCol "lat" |> Series.values |> Array.ofSeq -Chart.LineMapBox( +Chart.LineMapbox( longitudes=lon, latitudes=lat, ShowMarkers=true, Name="soos" ) -|> Chart.withMapBox( - MapBox.init( - Style = StyleParam.MapBoxStyle.OpenStreetMap, +|> Chart.withMapbox( + Mapbox.init( + Style = StyleParam.MapboxStyle.OpenStreetMap, Center = (-97.61142,38.84028) ) ) diff --git a/src/Plotly.NET/Plotly.NET.fsproj b/src/Plotly.NET/Plotly.NET.fsproj index 015b5e8a7..30f3a8f20 100644 --- a/src/Plotly.NET/Plotly.NET.fsproj +++ b/src/Plotly.NET/Plotly.NET.fsproj @@ -66,9 +66,9 @@ - - - + + + diff --git a/src/Plotly.NET/StyleParams.fs b/src/Plotly.NET/StyleParams.fs index b43ba64c7..0c1d0aa21 100644 --- a/src/Plotly.NET/StyleParams.fs +++ b/src/Plotly.NET/StyleParams.fs @@ -815,7 +815,7 @@ module StyleParam = /// 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 = + type MapboxStyle = // plotly presets | OpenStreetMap | WhiteBG @@ -826,13 +826,13 @@ module StyleParam = | StamenWatercolor // Mapbox presets - | MapBoxBasic - | MapBoxStreets - | MapBoxOutdoors - | MapBoxLight - | MapBoxDark - | MapBoxSatellite - | MapBoxSatelliteStreets + | MapboxBasic + | MapboxStreets + | MapboxOutdoors + | MapboxLight + | MapboxDark + | MapboxSatellite + | MapboxSatelliteStreets //Custom | Custom of string @@ -847,20 +847,20 @@ module StyleParam = | StamenToner -> "stamen-toner" | StamenWatercolor -> "stamen-watercolor" - | MapBoxBasic -> "basic" - | MapBoxStreets -> "streets" - | MapBoxOutdoors -> "outdoors" - | MapBoxLight -> "light" - | MapBoxDark -> "dark" - | MapBoxSatellite -> "satellite" - | MapBoxSatelliteStreets -> "satellite-streets" + | MapboxBasic -> "basic" + | MapboxStreets -> "streets" + | MapboxOutdoors -> "outdoors" + | MapboxLight -> "light" + | MapboxDark -> "dark" + | MapboxSatellite -> "satellite" + | MapboxSatelliteStreets -> "satellite-streets" | Custom s -> s - static member convert = MapBoxStyle.toString >> box + static member convert = MapboxStyle.toString >> box [] - type MapBoxLayerSourceType = + type MapboxLayerSourceType = | GeoJson | Vector | Raster @@ -872,10 +872,10 @@ module StyleParam = | Raster -> "raster" | Image -> "image" - static member convert = MapBoxLayerSourceType.toString >> box + static member convert = MapboxLayerSourceType.toString >> box [] - type MapBoxLayerType = + type MapboxLayerType = | Circle | Line | Fill @@ -889,11 +889,11 @@ module StyleParam = | Symbol -> "symbol" | Raster -> "raster" - static member convert = MapBoxLayerType.toString >> box + static member convert = MapboxLayerType.toString >> box [] - type MapBoxLayerSymbolPlacement = + type MapboxLayerSymbolPlacement = | Point | Line | LineCenter @@ -903,7 +903,7 @@ module StyleParam = | Line -> "line" | LineCenter -> "line-center" - static member convert = MapBoxLayerSymbolPlacement.toString >> box + static member convert = MapboxLayerSymbolPlacement.toString >> box //-------------------------- diff --git a/src/Plotly.NET/Trace.fs b/src/Plotly.NET/Trace.fs index a995fc5ca..6fcf2449b 100644 --- a/src/Plotly.NET/Trace.fs +++ b/src/Plotly.NET/Trace.fs @@ -1575,7 +1575,7 @@ module Trace = ) - static member ScatterMapBox + static member ScatterMapbox ( mode : StyleParam.Mode, ?Longitudes : #IConvertible seq, From 4c2bd4fd6cdbf0bc17b1ca7a00e7a6b8567b205e Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Fri, 25 Jun 2021 11:47:36 +0200 Subject: [PATCH 06/13] Rename MapBoxLayerSymbol.fs to MapboxLayerSymbol.fs --- src/Plotly.NET/{MapBoxLayerSymbol.fs => MapboxLayerSymbol.fs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/Plotly.NET/{MapBoxLayerSymbol.fs => MapboxLayerSymbol.fs} (99%) diff --git a/src/Plotly.NET/MapBoxLayerSymbol.fs b/src/Plotly.NET/MapboxLayerSymbol.fs similarity index 99% rename from src/Plotly.NET/MapBoxLayerSymbol.fs rename to src/Plotly.NET/MapboxLayerSymbol.fs index 59605e9c6..4778a876e 100644 --- a/src/Plotly.NET/MapBoxLayerSymbol.fs +++ b/src/Plotly.NET/MapboxLayerSymbol.fs @@ -52,4 +52,4 @@ type MapboxLayerSymbol() = mapBoxLayerSymbol - ) \ No newline at end of file + ) From b83757cab2e8bce4cdf74a3ae21bea4d4ce51555 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Fri, 25 Jun 2021 11:47:57 +0200 Subject: [PATCH 07/13] Rename MapBoxLayer.fs to MapboxLayer.fs --- src/Plotly.NET/{MapBoxLayer.fs => MapboxLayer.fs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/Plotly.NET/{MapBoxLayer.fs => MapboxLayer.fs} (99%) diff --git a/src/Plotly.NET/MapBoxLayer.fs b/src/Plotly.NET/MapboxLayer.fs similarity index 99% rename from src/Plotly.NET/MapBoxLayer.fs rename to src/Plotly.NET/MapboxLayer.fs index 117edd168..c5bb66747 100644 --- a/src/Plotly.NET/MapBoxLayer.fs +++ b/src/Plotly.NET/MapboxLayer.fs @@ -111,4 +111,4 @@ type MapboxLayer() = Name |> DynObj.setValueOpt mapBoxLayer "name" mapBoxLayer - ) \ No newline at end of file + ) From 994a675091e2e1cb3c6155138c75b6825e15ec94 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Fri, 25 Jun 2021 11:48:14 +0200 Subject: [PATCH 08/13] Rename MapBox.fs to Mapbox.fs --- src/Plotly.NET/{MapBox.fs => Mapbox.fs} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/Plotly.NET/{MapBox.fs => Mapbox.fs} (99%) diff --git a/src/Plotly.NET/MapBox.fs b/src/Plotly.NET/Mapbox.fs similarity index 99% rename from src/Plotly.NET/MapBox.fs rename to src/Plotly.NET/Mapbox.fs index 26c4dc9c1..1e8a5131c 100644 --- a/src/Plotly.NET/MapBox.fs +++ b/src/Plotly.NET/Mapbox.fs @@ -66,4 +66,4 @@ type Mapbox() = Layers |> DynObj.setValueOpt mapBox "layers" mapBox - ) \ No newline at end of file + ) From 4a04fbf784662b4299f3d8592513aecc1e9cc45e Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Tue, 6 Jul 2021 14:05:51 +0200 Subject: [PATCH 09/13] Add Point/LineGeo docs --- docs/5_1_geo-plots.fsx | 97 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 1 deletion(-) diff --git a/docs/5_1_geo-plots.fsx b/docs/5_1_geo-plots.fsx index ed720b843..084dda494 100644 --- a/docs/5_1_geo-plots.fsx +++ b/docs/5_1_geo-plots.fsx @@ -28,5 +28,100 @@ index: 2 *Summary:* This example shows how to create Point and Line charts on geo maps in F#. -*More coming soonTM* +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`: +*) + +#r "nuget: Deedle" +#r "nuget: FSharp.Data" +open Deedle +open FSharp.Data +open System.IO +open System.Text + +let data = + let dataString = Http.RequestString "https://raw.githubusercontent.com/plotly/datasets/c34aaa0b1b3cddad335173cb7bc0181897201ee6/2011_february_aa_flight_paths.csv" + let byteArray = Encoding.UTF8.GetBytes(dataString) + use stream = new MemoryStream(byteArray) + Frame.ReadCsv(stream,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***) From 2875e36119b507d8357e9d2bcbcde9ee51a76323 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Tue, 6 Jul 2021 17:21:57 +0200 Subject: [PATCH 10/13] Add PointMapbox and LineMapbox docs --- docs/6_1_mapbox-plots.fsx | 95 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/docs/6_1_mapbox-plots.fsx b/docs/6_1_mapbox-plots.fsx index a10cfab30..1c2cffee8 100644 --- a/docs/6_1_mapbox-plots.fsx +++ b/docs/6_1_mapbox-plots.fsx @@ -28,5 +28,98 @@ index: 2 *Summary:* This example shows how to create Point and Line charts on Mapbox maps in F#. -*More coming soonTM* +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***) From 4574d6bbfd1ed4c3d6bb9b6d77c111d79f52da40 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Tue, 6 Jul 2021 17:22:17 +0200 Subject: [PATCH 11/13] Use new Frame.ReadCsvString function to reduce LOC in some docs --- docs/5_1_geo-plots.fsx | 10 +++++----- docs/5_2_choropleth-map.fsx | 6 ++---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/docs/5_1_geo-plots.fsx b/docs/5_1_geo-plots.fsx index 084dda494..d068a990a 100644 --- a/docs/5_1_geo-plots.fsx +++ b/docs/5_1_geo-plots.fsx @@ -76,7 +76,9 @@ pointGeo |> GenericChart.toChartHTML (** -To connect the given (lon,lat) pairs via straight lines, use `Chart.LineGeo`: +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" @@ -87,10 +89,8 @@ open System.IO open System.Text let data = - let dataString = Http.RequestString "https://raw.githubusercontent.com/plotly/datasets/c34aaa0b1b3cddad335173cb7bc0181897201ee6/2011_february_aa_flight_paths.csv" - let byteArray = Encoding.UTF8.GetBytes(dataString) - use stream = new MemoryStream(byteArray) - Frame.ReadCsv(stream,true,separators=",") + 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"] diff --git a/docs/5_2_choropleth-map.fsx b/docs/5_2_choropleth-map.fsx index e48aa8cfc..f93391ccf 100644 --- a/docs/5_2_choropleth-map.fsx +++ b/docs/5_2_choropleth-map.fsx @@ -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") (** From ad7286292b6af61c9d039c4fa9a115ffebade5a1 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Wed, 7 Jul 2021 10:49:18 +0200 Subject: [PATCH 12/13] #91: Add ChoroplethMapbox chart with docs --- docs/5_2_choropleth-map.fsx | 5 +- docs/6_2_choropleth-mapbox.fsx | 118 ++++++++++++++++++++++++++++++++- src/Plotly.NET/Chart.fs | 52 +++++++++++++++ src/Plotly.NET/Playground.fsx | 15 ++++- src/Plotly.NET/Trace.fs | 57 +++++++++++++--- 5 files changed, 231 insertions(+), 16 deletions(-) diff --git a/docs/5_2_choropleth-map.fsx b/docs/5_2_choropleth-map.fsx index f93391ccf..f9633356b 100644 --- a/docs/5_2_choropleth-map.fsx +++ b/docs/5_2_choropleth-map.fsx @@ -237,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_2_choropleth-mapbox.fsx b/docs/6_2_choropleth-mapbox.fsx index 877c41a02..cbaedc850 100644 --- a/docs/6_2_choropleth-mapbox.fsx +++ b/docs/6_2_choropleth-mapbox.fsx @@ -28,5 +28,121 @@ index: 3 *Summary:* This example shows how to create choropleth maps using Mapbox layers in F#. -*More coming soonTM* +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/src/Plotly.NET/Chart.fs b/src/Plotly.NET/Chart.fs index fc6e0c25e..78084c19b 100644 --- a/src/Plotly.NET/Chart.fs +++ b/src/Plotly.NET/Chart.fs @@ -3177,3 +3177,55 @@ type Chart = ?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 + \ No newline at end of file diff --git a/src/Plotly.NET/Playground.fsx b/src/Plotly.NET/Playground.fsx index 498afa61e..f568f2d9a 100644 --- a/src/Plotly.NET/Playground.fsx +++ b/src/Plotly.NET/Playground.fsx @@ -131,9 +131,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 @@ -147,6 +145,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, diff --git a/src/Plotly.NET/Trace.fs b/src/Plotly.NET/Trace.fs index 6fcf2449b..e91e66d78 100644 --- a/src/Plotly.NET/Trace.fs +++ b/src/Plotly.NET/Trace.fs @@ -1170,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 ) = @@ -1196,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 -> @@ -1577,13 +1579,13 @@ module Trace = static member ScatterMapbox ( - mode : StyleParam.Mode, + mode : StyleParam.Mode, ?Longitudes : #IConvertible seq, ?Latitudes : #IConvertible seq, - ?Below: string, - ?Connectgaps : bool, - ?Fill : StyleParam.Fill, - ?Fillcolor + ?Below : string, + ?Connectgaps: bool, + ?Fill : StyleParam.Fill, + ?Fillcolor : string ) = (fun (trace:('T :> Trace)) -> @@ -1595,5 +1597,38 @@ module Trace = 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, + ?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" + 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 From aa58b4f680b86e1d172d5e49e233835803726888 Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Wed, 7 Jul 2021 12:06:47 +0200 Subject: [PATCH 13/13] #92: Add DensityMapbox Chart and docs --- docs/6_3_density-mapbox.fsx | 46 ++++++++++++++- src/Plotly.NET/Chart.fs | 108 ++++++++++++++++++++++++++++++++-- src/Plotly.NET/Playground.fsx | 26 ++++++++ src/Plotly.NET/StyleParams.fs | 7 ++- src/Plotly.NET/Trace.fs | 40 +++++++++++++ 5 files changed, 219 insertions(+), 8 deletions(-) diff --git a/docs/6_3_density-mapbox.fsx b/docs/6_3_density-mapbox.fsx index 436710483..43bd88f63 100644 --- a/docs/6_3_density-mapbox.fsx +++ b/docs/6_3_density-mapbox.fsx @@ -28,6 +28,48 @@ index: 4 *Summary:* This example shows how to create DensityMapbox charts in F#. -*More coming soonTM* +`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. -*) \ No newline at end of file +*) +// 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/src/Plotly.NET/Chart.fs b/src/Plotly.NET/Chart.fs index 78084c19b..24fd84028 100644 --- a/src/Plotly.NET/Chart.fs +++ b/src/Plotly.NET/Chart.fs @@ -3213,9 +3213,9 @@ type Chart = Trace.initChoroplethMapbox ( TraceStyle.ChoroplethMapbox ( - Z = z, - Locations = locations, - GeoJson = geoJson, + Z = z, + Locations = locations, + GeoJson = geoJson, ?FeatureIdKey = FeatureIdKey, ?Text = Text, ?Below = Below, @@ -3228,4 +3228,104 @@ type Chart = ) ) |> GenericChart.ofTraceObject - \ No newline at end of file + + /// + /// 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/Playground.fsx b/src/Plotly.NET/Playground.fsx index f568f2d9a..559f71db4 100644 --- a/src/Plotly.NET/Playground.fsx +++ b/src/Plotly.NET/Playground.fsx @@ -63,6 +63,32 @@ 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) diff --git a/src/Plotly.NET/StyleParams.fs b/src/Plotly.NET/StyleParams.fs index 0c1d0aa21..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. diff --git a/src/Plotly.NET/Trace.fs b/src/Plotly.NET/Trace.fs index e91e66d78..115817e19 100644 --- a/src/Plotly.NET/Trace.fs +++ b/src/Plotly.NET/Trace.fs @@ -1610,6 +1610,7 @@ module Trace = ?Below : string, ?Colorscale : StyleParam.Colorscale, ?Colorbar : Colorbar, + ?Showscale : bool, ?ZAuto : bool, ?ZMin : float, ?ZMid : float, @@ -1625,6 +1626,45 @@ module Trace = 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"