Scatter Plots in F#

How to make scatter plots in F# with Plotly.


Plotly is known for its graphing libraries, but it's also a broader ecosystem for building interactive data apps, AI data analysis tools, and deploying and hosting Dash apps. Explore the full set of tools and platforms designed to help turn data into action. Discover Plotly.

Note: We are retiring documentation for R, MATLAB, Julia, and F#. Learn more about this change here.

Scatter Plots in Fsharp

How to make scatter plots in F# with Plotly.NET

In [1]:
#r "nuget: Plotly.NET,  2.0.0-preview.8"
#r "nuget: newtonsoft.json"
#r "nuget: Plotly.NET.Interactive,  2.0.0-preview.8"
#r "nuget: FSharp.Data"
#r "nuget: Deedle"

open Plotly.NET
Installed Packages
  • Deedle, 2.4.3
  • FSharp.Data, 4.2.4
  • newtonsoft.json, 13.0.1
  • Plotly.NET, 2.0.0-preview.8
  • Plotly.NET.Interactive, 2.0.0-preview.8

Loading extensions from Plotly.NET.Interactive.dll

Added Kernel Extension including formatters for Plotly.NET charts.

Scatter and line plots

With Chart.Scatter, each data point is represented as a marker point, whose location is given by the x and y arrays.

Simple Scatter Plot

In [2]:
let ts = [0. .. 0.1 .. 10.]
let ys = ts |> Seq.map (Math.Sin)
Chart.Scatter(ts, ys, mode=StyleParam.Mode.Markers)
Out[2]:
In [3]:
open Plotly.NET

let x=[|0; 1; 2; 3; 4|]
let y=[|0; 1; 4; 9; 16|]

Chart.Scatter(x, y , mode=StyleParam.Mode.Markers_Text)
    |> Chart.withXAxisStyle ("x")
    |> Chart.withYAxisStyle ("y")
Out[3]:

Line and Scatter Plots

settting mode in Chart.Scatter to StyleParam.Mode.Markers, StyleParam.Mode.Lines_Markers helps to visualize markers along with lines

In [4]:
open Plotly.NET

let n = 100.
let random_x = [0. .. 1. .. n]

let rand = new Random()

let nextFloat(max,min)= rand.NextDouble() * (max - min) + min

let generate() = random_x |> Seq.map (fun _-> nextFloat(-2., 2.))

let random_y0 = generate () |> Seq.map(fun x-> x + 5.)
let random_y1 = generate ()
let random_y2 = generate () |> Seq.map(fun x-> x - 5.)

[
    Chart.Scatter(random_x, random_y0, mode=StyleParam.Mode.Markers, Name="Markers");
    Chart.Scatter(random_x, random_y1, mode=StyleParam.Mode.Lines_Markers, Name="Lines_Markers");
    Chart.Scatter(random_x, random_y2, mode=StyleParam.Mode.Lines, Name="Lines");
] |> Chart.combine
Out[4]:

Bubble Scatter Plots

Scatter plots with variable-sized circular markers are often known as bubble charts. In bubble charts, a third dimension of the data is shown through the size of markers.

MultiSizes property allows to set variable sizes for the marker symbols

In [5]:
open Plotly.NET
open Plotly.NET.TraceObjects

let xs =[1; 2; 3; 4]
let ys =[10;11; 12; 13]

let colors = [|"#4287f5";"#cb23fa";"#23fabd";"#ff7b00"|] |> Array.map (fun c -> Color.fromString(c))
let marker = Marker.init(MultiSizes=[40; 60; 80; 100]);
marker?color <- colors

Chart.Scatter(xs, ys, StyleParam.Mode.Markers, Name="Markers")
        |> Chart.withMarker(marker)
Out[5]:

Style Scatter Plots

There are many properties of the scatter chart type that control different aspects of the appearance of the plot. Here are a few examples

In [6]:
open Plotly.NET
open System

let ts = [0. .. 0.1 .. 10.]
let sins = ts |> Seq.map (Math.Sin)
let coss = ts |> Seq.map (Math.Cos)

[
    Chart.Scatter(ts, sins, StyleParam.Mode.Markers, Name ="sin");
    Chart.Scatter(ts, coss, StyleParam.Mode.Markers, Name ="cos")
] |> Chart.combine 
  |> Chart.withMarker(Marker.init(10, Line = Line.init(Width=2.)))
  |> Chart.withXAxisStyle("", Zeroline=false)
  |> Chart.withYAxisStyle("", ZeroLine=false)
  |> Chart.withTitle("Styled Scatter")
Out[6]:

Setting color

In [7]:
open Plotly.NET
open Plotly.NET.TraceObjects
open FSharp.Data
open Deedle

let data=
    Http.RequestString "https://raw.githubusercontent.com/plotly/datasets/master/iris.csv"
    |> fun csv -> Frame.ReadCsvString(csv,true,separators=",")

let getColumnData column=
        data
        |> Frame.getCol column
        |> Series.values
        |> Array.ofSeq

let SepalWidth:float[] = getColumnData "SepalWidth" 
let SepalLength:float[] = getColumnData "SepalLength" 
let PetalLength:float[] = getColumnData "PetalLength"
let PetalWidth:float[] = getColumnData "PetalWidth"
let colors = getColumnData "Name"  |> Array.map (fun name -> match name with
                                                                |"Iris-setosa" -> Color.fromString "red"
                                                                |"Iris-versicolor" -> Color.fromString "blue"
                                                                |_ -> Color.fromString "deeppink") |> Color.fromColors
                                
 

let marker = Marker.init(Color=colors)

Chart.Scatter(x=SepalWidth, y=SepalLength, mode=StyleParam.Mode.Markers, Labels=PetalWidth)
    |> Chart.withXAxisStyle ("sepal_width")
    |> Chart.withYAxisStyle ("sepal_length")
    |> Chart.withMarker(marker)
Out[7]:

Data Labels on Hover

In [8]:
open Plotly.NET
open FSharp.Data
open Plotly.NET.TraceObjects

[<Literal>]
let CsvPath = "https://raw.githubusercontent.com/plotly/datasets/master/2014_usa_states.csv"

type Dataset = CsvProvider<CsvPath>
let datasetItems = Dataset.GetSample()

let postalCodes = datasetItems.Rows |> Seq.map(fun x -> x.Postal)
let population = datasetItems.Rows |> Seq.map(fun x -> x.Population)
let states = datasetItems.Rows |> Seq.map(fun x -> x.State)

let marker = Marker.init()
marker?color <- population 

Chart.Point(postalCodes, population, Labels = states) 
  |> Chart.withMarker(marker)
  |> Chart.withTitle("Population of USA States")
Out[8]:

Scatter with a Color Dimension

In [9]:
open Plotly.NET.TraceObjects

let xs = [0. .. 1. .. 500.] 
let ys = xs |> Seq.map (fun _ -> nextFloat(-3., 4.))

let marker = Marker.init(Size = 16, Colorscale=StyleParam.Colorscale.Viridis, Showscale=true)
marker?color <- ys //Workaround

Chart.Point(xs, ys) 
|> Chart.withMarker(marker)
Out[9]:

Large Data Sets

In Plotly.NET you can implement WebGL with UseWebGL property for increased speed, improved interactivity, and the ability to plot even more data!

In [10]:
open Plotly.NET

let series = [0. .. 1. .. 100000.]
let xs = series |> Seq.map (fun x-> nextFloat(-x, x)) 
let ys = series |> Seq.map (fun x-> nextFloat(-x, x))

let marker = Marker.init(Colorscale=StyleParam.Colorscale.Viridis, Line=Line.init(Width=1.))
marker?color <-ys

Chart.Scatter(xs, ys, StyleParam.Mode.Markers, UseWebGL= true) 
  |> Chart.withMarker(marker)
Out[10]:
In [11]:
#r "nuget: FSharp.Stats"
Installed Packages
  • FSharp.Stats, 0.4.2
In [12]:
open Plotly.NET

open FSharp.Stats.Distributions

let n  = 100000

let rs = 
    let normal = Continuous.uniform -1. 1.
    Array.init n (fun _ -> normal.Sample())

let thetas = 
    let normal = Continuous.uniform 0.0 (2.*Math.PI)
    Array.init n (fun _ -> normal.Sample())
    
let xs = thetas |> Seq.zip rs |> Seq.map(fun (r,t)-> r*Math.Cos(t) )
let ys = thetas |> Seq.zip rs |> Seq.map(fun (r,t)-> r*Math.Sin(t))

let colors = series |> Seq.map (fun _ -> nextFloat(0. ,1.)) |> Seq.cast<IConvertible> |> Color.fromColorScaleValues
let marker = Marker.init(Colorscale=StyleParam.Colorscale.Viridis, Line=Line.init(Width=01.),Color=colors)


Chart.Scatter(xs, ys, StyleParam.Mode.Markers, UseWebGL= true) 
|> Chart.withMarker(marker)
Out[12]: