F# Charting


F# Charting: Point and Line Charts

Summary: This example shows how to create line and point charts in F#.

A line or a point chart can be created using the Chart.Line and Chart.Point methods. When generating a very large number of points or lines, it is better to use Chart.FastLine and Chart.FastPoint. These are special types of charts that do not support as many visual features but are more efficient.

When using F# Interactive, each of these examples needs to be evaluated separately. This way, F# Interactive invokes a handler that automatically shows the created chart.

A Simple Line Chart

The following example calls the Chart.Line method with a list of X and Y values as tuples. The snippet generates values of a simple function, f(x)=x^2. The values of the function are generated for X ranging from 1 to 100. The chart generated is shown below.

1: 
2: 
3: 
4: 
5: 
6: 
// On Mac OSX use FSharp.Charting.Gtk.fsx
#I "packages/FSharp.Charting"
#load "FSharp.Charting.fsx"

open FSharp.Charting
open System
1: 
2: 
// Drawing graph of a 'square' function 
Chart.Line [ for x in 1.0 .. 100.0 -> (x, x ** 2.0) ]

Chart

Pipelining into Chart.Line

The following example generates a list containing both X and Y values.

1: 
2: 
3: 
// Generates 2D curve using list of tuples
let curvyData = [ for i in 0.0 .. 0.02 .. 2.0 * Math.PI -> (sin i, cos i * sin i) ] 
curvyData |> Chart.Line

Chart

Specifying only Y values

The following example below shows that you may also simply give a set of Y values, rather than (X,Y) value pairs.

1: 
2: 
// Generates 2D curve using only Y values
Chart.Line [ for x in 1.0 .. 100.0 -> x * x * sin x ]

Chart

It uses a sequence expression ranging from 0 to 2π with a step size 0.02. This produces a large number of points, so the snippet uses the Chart.Line method to draw the chart. When using a single list as the data source, it is also possible to elegantly use the pipelining (|> operator).

A Point Chart

The following example shows how to generate a scatter plot. It uses a list to specify the X and Y coordinates of the points.

1: 
2: 
3: 
4: 
// Draw scatter plot  of points
let rnd = new Random()
let rand() = rnd.NextDouble()
let randomPoints = [ for i in 0 .. 1000 -> rand(), rand() ]
1: 
Chart.Point randomPoints

Chart

Specifying Minimums, Maximums and other properties on a Line Chart

The following example shows how to set the name and Y axis minimum properties on the chart and use log-distribution for the X axis.

1: 
2: 
let highData = [ for x in 1.0 .. 100.0 -> (x, 3000.0 + x ** 2.0) ]
Chart.Line(highData,Name="Rates").WithYAxis(Min=2000.0).WithXAxis(Log=true)

Chart

Combining Line Charts

The following example shows how to combine several line charts and give each data set a name. A legend is added automatically when names are used for data sets.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
let futureDate numDays = DateTime.Today.AddDays(float numDays)

let expectedIncome = 
  [ for x in 1 .. 100 -> 
      futureDate x, 1000.0 + rand() * 100.0 * exp (float x / 40.0) ]
let expectedExpenses = 
  [ for x in 1 .. 100 -> 
      futureDate x, rand() * 500.0 * sin (float x / 50.0) ]
let computedProfit = 
  (expectedIncome, expectedExpenses) 
  ||> List.map2 (fun (d1,i) (d2,e) -> (d1, i - e))
1: 
Chart.Line(expectedIncome,Name="Income")

Chart

1: 
Chart.Line(expectedExpenses,Name="Expenses")

Chart

1: 
Chart.Line(computedProfit,Name="Profit")

Chart

1: 
2: 
3: 
4: 
Chart.Combine(
   [ Chart.Line(expectedIncome,Name="Income")
     Chart.Line(expectedExpenses,Name="Expenses") 
     Chart.Line(computedProfit,Name="Profit") ])

Chart

Multiple items
namespace FSharp

--------------------
namespace Microsoft.FSharp
namespace FSharp.Charting
namespace System
type Chart =
  static member Area : data:seq<#value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string -> GenericChart
  static member Area : data:seq<#key * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string -> GenericChart
  static member Bar : data:seq<#value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string -> GenericChart
  static member Bar : data:seq<#key * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string -> GenericChart
  static member BoxPlotFromData : data:seq<#key * #seq<'a2>> * ?Name:string * ?Title:string * ?Color:Color * ?XTitle:string * ?YTitle:string * ?Percentile:int * ?ShowAverage:bool * ?ShowMedian:bool * ?ShowUnusualValues:bool * ?WhiskerPercentile:int -> GenericChart (requires 'a2 :> value)
  static member BoxPlotFromStatistics : data:seq<#key * #value * #value * #value * #value * #value * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string * ?Percentile:int * ?ShowAverage:bool * ?ShowMedian:bool * ?ShowUnusualValues:bool * ?WhiskerPercentile:int -> GenericChart
  static member Bubble : data:seq<#value * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string * ?BubbleMaxSize:int * ?BubbleMinSize:int * ?BubbleScaleMax:float * ?BubbleScaleMin:float * ?UseSizeForLabel:bool -> GenericChart
  static member Bubble : data:seq<#key * #value * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string * ?BubbleMaxSize:int * ?BubbleMinSize:int * ?BubbleScaleMax:float * ?BubbleScaleMin:float * ?UseSizeForLabel:bool -> GenericChart
  static member Candlestick : data:seq<#value * #value * #value * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string -> CandlestickChart
  static member Candlestick : data:seq<#key * #value * #value * #value * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Color * ?XTitle:string * ?YTitle:string -> CandlestickChart
  ...

Full name: FSharp.Charting.Chart
static member Chart.Line : data:seq<#value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Drawing.Color * ?XTitle:string * ?YTitle:string -> ChartTypes.GenericChart
static member Chart.Line : data:seq<#key * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Drawing.Color * ?XTitle:string * ?YTitle:string -> ChartTypes.GenericChart
val x : float
val curvyData : (float * float) list

Full name: PointAndLineCharts.curvyData
val i : float
type Math =
  static val PI : float
  static val E : float
  static member Abs : value:sbyte -> sbyte + 6 overloads
  static member Acos : d:float -> float
  static member Asin : d:float -> float
  static member Atan : d:float -> float
  static member Atan2 : y:float * x:float -> float
  static member BigMul : a:int * b:int -> int64
  static member Ceiling : d:decimal -> decimal + 1 overload
  static member Cos : d:float -> float
  ...

Full name: System.Math
field Math.PI = 3.14159265359
val sin : value:'T -> 'T (requires member Sin)

Full name: Microsoft.FSharp.Core.Operators.sin
val cos : value:'T -> 'T (requires member Cos)

Full name: Microsoft.FSharp.Core.Operators.cos
val rnd : Random

Full name: PointAndLineCharts.rnd
Multiple items
type Random =
  new : unit -> Random + 1 overload
  member Next : unit -> int + 2 overloads
  member NextBytes : buffer:byte[] -> unit
  member NextDouble : unit -> float

Full name: System.Random

--------------------
Random() : unit
Random(Seed: int) : unit
val rand : unit -> float

Full name: PointAndLineCharts.rand
Random.NextDouble() : float
val randomPoints : (float * float) list

Full name: PointAndLineCharts.randomPoints
val i : int
static member Chart.Point : data:seq<#value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Drawing.Color * ?XTitle:string * ?YTitle:string * ?MarkerColor:Drawing.Color * ?MarkerSize:int -> ChartTypes.GenericChart
static member Chart.Point : data:seq<#key * #value> * ?Name:string * ?Title:string * ?Labels:#seq<string> * ?Color:Drawing.Color * ?XTitle:string * ?YTitle:string * ?MarkerColor:Drawing.Color * ?MarkerSize:int -> ChartTypes.GenericChart
val highData : (float * float) list

Full name: PointAndLineCharts.highData
val futureDate : numDays:int -> DateTime

Full name: PointAndLineCharts.futureDate
val numDays : int
Multiple items
type DateTime =
  struct
    new : ticks:int64 -> DateTime + 10 overloads
    member Add : value:TimeSpan -> DateTime
    member AddDays : value:float -> DateTime
    member AddHours : value:float -> DateTime
    member AddMilliseconds : value:float -> DateTime
    member AddMinutes : value:float -> DateTime
    member AddMonths : months:int -> DateTime
    member AddSeconds : value:float -> DateTime
    member AddTicks : value:int64 -> DateTime
    member AddYears : value:int -> DateTime
    ...
  end

Full name: System.DateTime

--------------------
DateTime()
   (+0 other overloads)
DateTime(ticks: int64) : unit
   (+0 other overloads)
DateTime(ticks: int64, kind: DateTimeKind) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, calendar: Globalization.Calendar) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: DateTimeKind) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: Globalization.Calendar) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : unit
   (+0 other overloads)
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: DateTimeKind) : unit
   (+0 other overloads)
property DateTime.Today: DateTime
DateTime.AddDays(value: float) : DateTime
Multiple items
val float : value:'T -> float (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float

--------------------
type float = Double

Full name: Microsoft.FSharp.Core.float

--------------------
type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>
val expectedIncome : (DateTime * float) list

Full name: PointAndLineCharts.expectedIncome
val x : int
val exp : value:'T -> 'T (requires member Exp)

Full name: Microsoft.FSharp.Core.Operators.exp
val expectedExpenses : (DateTime * float) list

Full name: PointAndLineCharts.expectedExpenses
val computedProfit : obj

Full name: PointAndLineCharts.computedProfit
Multiple items
module List

from Microsoft.FSharp.Collections

--------------------
static member Chart.Combine : charts:seq<ChartTypes.GenericChart> -> ChartTypes.GenericChart
Fork me on GitHub