Horizontal Bar in F#

How to make horizontal bar charts 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.

In [1]:
#r "nuget: Plotly.NET, 2.0.0-preview.8"
#r "nuget: Plotly.NET.Interactive, 2.0.0-preview.8"
open Plotly.NET
Installed Packages
  • 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.

Basic Horizontal Bar Chart

In [2]:
Chart.Bar(["giraffes"; "orangutans"; "monkeys"], [20;14;23])
Out[2]:

Colored Horizontal Bar Chart

In [3]:
open Plotly.NET.TraceObjects

let markerStyle1 = Marker.init(Color=Color.fromString "rgba(246, 78, 139, 0.6)",Line=Line.init(Color=Color.fromString "rgba(246, 78, 139, 1.0)",Width=3.))
let markerStyle2 = Marker.init(Color=Color.fromString "rgba(58, 71, 80, 0.6)",Line=Line.init(Color=Color.fromString "rgba(58, 71, 80, 1.0)",Width=3.))

[
    Chart.Bar(["giraffes"; "orangutans"; "monkeys"], [20;14;23],Marker=markerStyle1,Name="SF Zoo")    
    Chart.Bar(["giraffes"; "orangutans"; "monkeys"], [12;18;29],Marker=markerStyle2,Name="LA Zoo")    
]
|> Chart.combine
|> Chart.withLayout(Layout.init(BarMode = StyleParam.BarMode.Stack))
Out[3]:

Color Palette for Bar Chart

In [4]:
open Plotly.NET.TraceObjects
open Plotly.NET.LayoutObjects

let n = 4
let topLabels = ["Strongly<br>agree"; "Agree"; "Neutral"; "Disagree"; "Strongly<br>disagree"]
let colors = [|"rgba(38, 24, 74, 0.8)"; "rgba(71, 58, 131, 0.8)"; "rgba(122, 120, 168, 0.8)"; "rgba(164, 163, 204, 0.85)"; "rgba(190, 192, 213, 1)"|]
let xData = [[|21; 30; 21; 16; 12;|];
             [|24; 31; 19; 15; 11;|];
             [|27; 26; 23; 11; 13;|];
             [|29; 24; 15; 18; 14;|]]
let yData = ["The course was effectively<br>organized";
             "The course developed my<br>abilities and skills " +
             "for<br>the subject"; "The course developed " +
             "my<br>ability to think critically about<br>the subject";
             "I would recommend this<br>course to a friend"]

let fSum x = (Array.scan (+) 0 x).[0..n]

let cumX j= fSum xData.[j]
            |> Array.mapi (fun i x -> if i > 0 then x+xData.[0].[i]/2 else xData.[0].[0]/2)

let top_annotation =[ for i in 0..4 -> Annotation.init(XRef="x",YRef="paper",
                                                        X=(cumX 0 |> Array.item i),
                                                        Y=1.1,
                                                        ShowArrow = false,
                                                        Text=topLabels.[i])]

let label_annotations = [for i in 0..4 -> 
                                [for j in 0..3 -> 
                                        Annotation.init(XRef="x",YRef="y",
                                                        X=(cumX j |> Array.item i),
                                                        Y=yData.[j],
                                                        ShowArrow = false,
                                                        Font = Font.init(Family = StyleParam.FontFamily.Arial, Size=14., Color =Color.fromString "white"),
                                                        Text=string xData.[j].[i]+"%")]] |> Seq.concat |> Seq.toList

let annotations = top_annotation @ label_annotations

let markerStyle i= Marker.init(Color=Color.fromString (colors.[i]),Line=Line.init(Color=Color.fromString "rgb(248, 248, 249)",Width=1.))

let y i= Array.init n (fun _ -> yData.[i])

[for j in 0..n  -> [for i in 0..3 -> Chart.Bar(keys=y i,values=[xData.[i].[j]],Marker=markerStyle j)] ] |> Seq.concat
|> Chart.combine
|> Chart.withLayout(Layout.init(BarMode=StyleParam.BarMode.Stack,
                        Margin = Margin.init(Left = 120, Right = 10, Top = 140, Bottom = 80),
                        ShowLegend=false,
                        Annotations=annotations,
                        PaperBGColor =Color.fromString "rgb(248, 248, 255)", PlotBGColor =Color.fromString "rgb(248, 248, 255)",
                        Font = Font.init(Family = StyleParam.FontFamily.Arial, Size=14., Color =Color.fromString "rgb(67, 67, 67)")))

|> Chart.withXAxis(LinearAxis.init(Domain = StyleParam.Range.MinMax (0.15, 1.), ZeroLine = false, ShowTickLabels = false, ShowLine = false, ShowGrid = false ))
|> Chart.withYAxis(LinearAxis.init(ZeroLine = false, ShowTickLabels = false, ShowLine = false, ShowGrid = false ))
Out[4]:

Bar Chart with Line Plot

In [5]:
open Plotly.NET

let ySaving = [|1.3586; 2.2623000000000002; 4.9821999999999997; 6.5096999999999996; 7.4812000000000003; 7.5133000000000001;15.2148;17.520499999999998|]
let yNetWorth = [|93453.919999999998; 81666.570000000007; 69889.619999999995; 78381.529999999999; 141395.29999999999; 92969.020000000004; 66090.179999999993; 122379.3|]
let x = [|"Japan"; "United Kingdom"; "Canada"; "Netherlands"; "United States"; "Belgium"; "Sweden"; "Switzerland"|]
let xs = Seq.zip yNetWorth x

let barChart = (Chart.Bar(x, ySaving, Name="Household savings, percentage of household disposable income", Marker = Marker.init(Color =Color.fromString "rgba(50, 171, 96, 0.6)", Line = Line.init(Color =Color.fromString "rgba(50, 171, 96, 1.0)", Width =1.)))
                |> Chart.withYAxis(LinearAxis.init(ShowGrid = false, ShowLine = false, ShowTickLabels = true,Domain=StyleParam.Range.MinMax(0.,0.85)))
                |> Chart.withXAxis(LinearAxis.init(ShowGrid = true, ShowLine = false, ShowTickLabels = true, ZeroLine = false,Domain=StyleParam.Range.MinMax(0.,0.42))))

let lineChart =  (Chart.Line(xs, Color =Color.fromString "rgb(128, 0, 128)", Name = "Household net worth, Million USD/capita")
                    |> Chart.withYAxis(LinearAxis.init(ShowGrid = false, ShowLine = true, ShowTickLabels = false, LineColor =Color.fromString "rgba(102, 102, 102, 0.8)", LineWidth = 2.,Domain=StyleParam.Range.MinMax(0.,0.85)))
                    |> Chart.withXAxis(LinearAxis.init(ShowGrid = true, ShowLine = false, ShowTickLabels = true, ZeroLine = false, Side = StyleParam.Side.Top, DTick = 25000,Domain=StyleParam.Range.MinMax(0.47,1.))))


let annotations = [for (ydn, yd, xd) in Array.zip3 yNetWorth ySaving x->

                                                     [|Annotation.init(XRef="x1",YRef="y1",
                                                        X=yd+3.,
                                                        Y=xd,
                                                        ShowArrow = false,
                                                        Font = Font.init(Family = StyleParam.FontFamily.Arial, Size=14., Color =Color.fromString "rgb(50, 171, 96)"),
                                                        Text=string yd+"%");

                                                        Annotation.init(XRef="x2",YRef="y2",
                                                        X=ydn-20000.,
                                                        Y=xd,
                                                        ShowArrow = false,
                                                        Font = Font.init(Family = StyleParam.FontFamily.Arial, Size=14., Color =Color.fromString "rgb(128, 0, 128)"),
                                                        Text=string ydn+"M")|] ] |> Array.concat

let labelAnnotation = Annotation.init(XRef="paper",YRef="paper",
                                            X= 0,
                                            Y= -0.109,
                                            ShowArrow = false,
                                            Font = Font.init(Family = StyleParam.FontFamily.Arial, Size=10., Color =Color.fromString "rgb(150,150,150)"),
                                            Text="OECD (2015), Household savings (indicator), Household net worth (indicator). doi: 10.1787/cfc6f499-en (Accessed on 05 June 2015")

let allAnnotations = annotations|> Array.append [|labelAnnotation|]

[barChart;lineChart]
|> Chart.Grid(1,2)
|> Chart.withLayout(Layout.init(Width = 1000, Margin = Margin.init(Top = 70., Bottom = 70., Left = 100., Right = 20.), Legend = Legend.init(X = 0.029, Y = 1.100)))
|> Chart.withAnnotations(allAnnotations)
Out[5]: