Benutzer:MovGP0/F♯/Data Visualisation

aus Wikipedia, der freien Enzyklopädie
   MovGP0        Über mich        Hilfen        Artikel        Weblinks        Literatur        Zitate        Notizen        Programmierung        MSCert        Physik      


Data Visualisation

Simple WebForms GUI

open System.Windows.Forms

let form = new Form(Text = "First Form")
let button = new Button(Text = "Close", Dock = DockStyle.Fill )
button.Click.Add(fun _ -> Application.Exit() |> ignore)
form.Controls.Add button
form.Show()

Example

Agents.fs
namespace HelloWorld.Agents

open System
   
type Agent<'T> = MailboxProcessor<'T>

type CounterMessage = 
    | Update of float
    | Reset

module Helpers =
    let generateRandomNumber n = 
        let rnd = new Random()
        float(rnd.Next(n, 100))

module MaxAgent = 
    let sampleAgent = Agent.Start(fun inbox -> 
        let rec loop m = async {
            let! msg = inbox.Receive()
            match msg with
            | Reset -> 
                return! loop 0.0
            | Update value -> 
                let m = max m value
                printfn "Max: %f" m
                do! Async.Sleep 1000
                return! loop m
        }
        loop 0.0
    )
Gui.fs
namespace HelloWorld.Gui

open System
open System.Drawing
open System.Windows.Forms
open HelloWorld.Agents

module Gui = 
    type public SampleForm() as form = 
        inherit Form()

        let valueLabel = new Label(Location = new Point(25, 25))
        let startButton = new Button(Location = new Point(25, 50))
        let sendButton = new Button(Location = new Point(25, 75))
        let agent = MaxAgent.sampleAgent
        let initControls = 
            valueLabel.Text <- "Sample Text"
            startButton.Text <- "Start"
            sendButton.Text <- "Send value to agent"
        do
            initControls
            
            form.Controls.Add(valueLabel)
            form.Controls.Add(startButton)
            form.Text <- "Sample App in F#"
            startButton.Click.AddHandler(new EventHandler(fun sender eventArgs -> form.eventStartButton_Click(sender, eventArgs)))

        member form.eventStartButton_Click(sender: obj, eventArgs:EventArgs) = 
            let random = Helpers.generateRandomNumber 5
            printf "Sending value to agent: %f" random
            agent.Post(Update random)
            ()
Program.fs
open System
open System.Drawing
open System.Windows.Forms
open HelloWorld.Gui

module Main =
    [<STAThread>]
    do 
        Application.EnableVisualStyles()
        Application.SetCompatibleTextRenderingDefault false
        let view = new Gui.SampleForm()
        Application.Run view

Grid View

open System
open System.Drawing
open System.Windows.Forms

[<STAThread>]
do
    let form = new Form(Visible = true, 
                        Text = "Displaying data in F#", 
                        TopMost = true, 
                        Size = Drawing.Size(600,600))
    
    let data = new DataGridView(Dock = DockStyle.Fill, 
                                Text = "Data grid", 
                                Font = new Drawing.Font("Lucidia Console", 10.0f), 
                                ForeColor = Color.DarkBlue)

    form.Controls.Add data
    
    data.DataSource <- [| ("ORCL", 32.2000, 31.1000, 31.1200, 0.0100)
                          ("MSFT", 72.050, 72.3100, 72.4000, 0.0800)
                          ("EBAY", 58.250, 58.5200, 58.5100, 0.0100) |]
    
    Application.Run form

Stock Data Charting

Line Chart in WinForms

open System
open System.Drawing
open System.Net
open System.Windows.Forms
open System.Windows.Forms.DataVisualization.Charting
open FSharp.Data
open Microsoft.FSharp.Control.WebExtensions

type Stocks = CsvProvider<"http://ichart.finance.yahoo.com/table.csv?s=ORCL&d=9&e=23&f=2012&g=d&a=2&b=13&c=1986&ignore=.csv">

[<STAThread>]
do
    let chart = new Chart(Dock = DockStyle.Fill)
    let area = new ChartArea("Main")
    chart.ChartAreas.Add area
    chart.Legends.Add(new Legend())

    let mainForm = new Form(Visible = true, 
                            TopMost = true, 
                            Width = 700, 
                            Height = 500)
    mainForm.Text <- "Yahoo! Finance data in F#"
    mainForm.Controls.Add chart

    // create series of stock price
    let stockPrice = new Series "stock price"
    stockPrice.ChartType <- SeriesChartType.Line
    stockPrice.BorderWidth <- 2
    stockPrice.Color <- Color.DarkGray
    chart.Series.Add stockPrice

    // create series for moving average
    let movingAvg = new Series "moving average"
    movingAvg.ChartType <- SeriesChartType.Line
    movingAvg.BorderWidth <- 2
    movingAvg.Color <- Color.Blue
    chart.Series.Add movingAvg

    // create series for upper band
    let upperBand = new Series "upper band"
    upperBand.ChartType <- SeriesChartType.Line
    upperBand.BorderWidth <- 2
    upperBand.Color <- Color.Red
    chart.Series.Add upperBand

    // create new series for lower band
    let lowerBand = new Series "lower band"
    lowerBand.ChartType <- SeriesChartType.Line
    lowerBand.BorderWidth <- 2
    lowerBand.Color <- Color.Green
    chart.Series.Add lowerBand

    // parse CSV
    let getPrices () = 
        let data = Stocks.GetSample()
        query {
           for stock in data.Rows do 
           // take 2500
           yield (float stock.Close)
        }

    // calculate moving average
    let movingAverage n (prices:seq<float>) = 
        prices
        |> Seq.windowed n
        |> Seq.map Array.sum
        |> Seq.map (fun a -> a / float n)

    // standard derivation
    let stdDev2 (values:seq<float>) = 
        let avg = Seq.average values
        values 
        |> Seq.fold (fun acc x -> acc + (1.0 / float (Seq.length values)) * (x - avg) ** 2.0) 0.0
        |> sqrt

    let movingStdDev n (prices:seq<float>) = 
        prices
        |> Seq.windowed n
        |> Seq.map stdDev2

    // plot result
    let sp = getPrices ()
    sp |> Seq.iter (stockPrice.Points.Add >> ignore)

    let ma = movingAverage 100 sp
    ma |> Seq.iter (movingAvg.Points.Add >> ignore)

    // bollinger bands (standard derivation)
    let ub = movingStdDev 100 sp

    Seq.zip ub ma 
    |> Seq.map (fun (a,b) -> b + 1.0 * a) 
    |> Seq.iter (upperBand.Points.Add >> ignore)

    Seq.zip ub ma 
    |> Seq.map (fun (a,b) -> b - 1.0 * a) 
    |> Seq.iter (lowerBand.Points.Add >> ignore)

    Application.Run mainForm

CandleStick Chart in FSI

#r @"..\packages\FSharp.Charting.0.90.6\lib\net40\FSharp.Charting.dll"
#r @"..\packages\FSharp.Data.2.0.9\lib\net40\FSharp.Data.dll"
#r @"System.Windows.Forms.DataVisualization"
#r @"System.Windows.Forms.DataVisualization.Design"

open System
open FSharp.Charting
open FSharp.Data
open Microsoft.FSharp.Control.WebExtensions
open System.Windows.Forms.DataVisualization.Charting

type Stocks = CsvProvider<"http://ichart.finance.yahoo.com/table.csv?s=ORCL&d=9&e=23&f=2012&g=d&a=2&b=13&c=1986&ignore=.csv">

module FSharpCharting = 
    fsi.AddPrinter (fun (chart : ChartTypes.GenericChart) -> 
                       chart.ShowChart()
                       "FSharpCharting")

let getOpenHighLowClosePrices () = 
    let data = Stocks.GetSample()
    query {
        for stock in data.Rows do 
        take 50
        yield (stock.Date, stock.High, stock.Low, stock.Open, stock.Close)
    }

Chart.Candlestick(getOpenHighLowClosePrices()).WithYAxis(Max = 34.0, Min = 30.0)

Bar Chart

#r @"System.Windows.Forms.DataVisualization"
#r @"System.Windows.Forms.DataVisualization.Design"

#r @"..\packages\FSharp.Charting.0.90.6\lib\net40\FSharp.Charting.dll"
#r @"..\packages\FSharp.Data.2.0.9\lib\net40\FSharp.Data.dll"
#r @"..\packages\MathNet.Numerics.3.0.2\lib\net40\MathNet.Numerics.dll"
#r @"..\packages\MathNet.Numerics.FSharp.3.0.2\lib\net40\MathNet.Numerics.FSharp.dll"

open System
open FSharp.Charting
open FSharp.Data
open MathNet.Numerics
open MathNet.Numerics.Distributions
open MathNet.Numerics.Statistics

module FSharpCharting = 
    fsi.AddPrinter (fun (chart : ChartTypes.GenericChart) -> 
                        chart.ShowChart()
                        "FSharpCharting")

// use Math.NET to create data
let dist = new Normal(0.0, 1.0)
let samples = dist.Samples() |> Seq.take 10000 |> Seq.toList
let histogram = new Histogram(samples, 35);

// convert from Math.NET values to FSharp Charting Columns
let values = 
    [0 .. (histogram.BucketCount - 1)] 
    |> Seq.map (fun i -> histogram.Item(i))
    |> Seq.map (fun item -> ((item.LowerBound + item.UpperBound) / 2.0, item.Count))

Chart.Column values