Created
October 14, 2021 23:24
-
-
Save jackparmer/d274b15561fd0b670921be76704e5cf3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!fsharp | |
#r "nuget:Dash.NET.Interactive,0.2.0-alpha.4" | |
#!fsharp | |
#r "nuget: FSharp.Data" | |
open FSharp.Data | |
let [<Literal>] Csv = "https://raw.githubusercontent.com/plotly/datasets/master/iris-id.csv" | |
type CsvData = CsvProvider<Csv> | |
let rows = CsvData.Load(Csv).Cache().Rows | |
let _ = Seq.head rows // skip the first line | |
#!fsharp | |
// Learn more about Dash.NET at https://plotly.github.io/Dash.NET/ | |
open Dash.NET.Suave | |
open Dash.NET.Html | |
open Dash.NET.DCC | |
open Dash.NET | |
open Plotly.NET | |
// Use plotly charts | |
let scatterPlot low high = | |
let filtered = Seq.filter (fun (x:CsvData.Row) -> x.Petal_width > low && x.Petal_width < high) rows | |
let points = Seq.map (fun (x:CsvData.Row) -> x.Sepal_width,x.Sepal_length) filtered | |
let petal_length = Seq.map (fun (x:CsvData.Row) -> 6*int(x.Petal_length)) filtered | |
let markers = TraceObjects.Marker.init(MultiSize=petal_length) | |
// Map species to different colors | |
let colorMap = function | "setosa" -> "#4287f5" | "versicolor" -> "#cb23fa" | "virginica" -> "#23fabd" | |
let spec = Seq.map (fun (x:CsvData.Row) -> x.Species) filtered | |
markers?color <- Seq.map colorMap spec | |
Chart.Scatter(points,StyleParam.Mode.Markers) | |
|> Chart.withMarker markers | |
|> Chart.withTitle("Iris Dataset") | |
|> Chart.withLayout (Layout.init (PlotBGColor = Color.fromString "#000", PaperBGColor = Color.fromString "#000")) | |
|> Chart.withXAxisStyle("Sepal Width") | |
|> Chart.withYAxisStyle("Sepal Length") | |
|> GenericChart.toFigure | |
// Layout for our dash app | |
let myLayout = | |
Html.div [ | |
Attr.children [ | |
Graph.graph "my-graph-id" []; | |
Html.p [ Attr.children "Petal Width:" ] | |
RangeSlider.rangeSlider "range-slider" [ | |
RangeSlider.Attr.min 0. | |
RangeSlider.Attr.max 2.5 | |
RangeSlider.Attr.step 0.1 | |
RangeSlider.Attr.marks ( | |
[ 0.; 2.5 ] | |
|> List.map (fun v -> v, v |> sprintf "%g" |> RangeSlider.Mark.Value) | |
|> Map.ofList | |
) | |
RangeSlider.Attr.value [ 0.5; 2. ] | |
RangeSlider.Attr.tooltip <| | |
RangeSlider.TooltipOptions.init ( | |
alwaysVisible = true, | |
placement = RangeSlider.TooltipPlacement.Bottom | |
) | |
] | |
] | |
Attr.style [ | |
StyleProperty ("background", "black") | |
StyleProperty ("color", "lightgrey") | |
StyleProperty ("font-family", "Arial") | |
StyleProperty ("padding", "0 50px 100px 50px") | |
] | |
] | |
let callback = | |
let outputTarget = "my-graph-id" @. CustomProperty "figure" | |
Callback.singleOut( | |
"range-slider" @. Value, | |
outputTarget, | |
(fun (sliderRange: decimal []) -> | |
let low, high = | |
let r1 = sliderRange.[0] | |
let r2 = sliderRange.[1] | |
if r1 < r2 then r1, r2 else r2, r1 | |
outputTarget => scatterPlot low high | |
), | |
PreventInitialCall = false | |
) | |
let dashApp = | |
DashApp.initDefault() | |
|> DashApp.withLayout myLayout | |
|> DashApp.addCallback callback | |
// display the application inside the notebook | |
dashApp |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment