Search code examples
f#fsharpchartf#-charting

Charting and Comparing Prices in F# - Chart.Combine will not produce graph


I'm working through the charting and comparing prices tutorial on tryfsharp.org and my Chart.Combine function in Fsharp.Charting library will not work, but, other charts, such as Chart.Line will work! Code below.

// Helper function returns dates & closing prices from 2012
let recentPrices symbol = 
    let data = stockData symbol (DateTime(2012,1,1)) DateTime.Now
    [ for row in data.Data -> row.Date.DayOfYear, row.Close ]


Chart.Line(recentPrices "AAPL", Name="Apple") //These two guys work when I try to plot them.
Chart.Line(recentPrices "MSFT", Name="Microsoft")

Chart.Combine( // This guy will not plot. Syntax found here: http://fsharp.github.io/FSharp.Charting/PointAndLineCharts.html
   [ Chart.Line(recentPrices "AAPL", Name="Apple")
     Chart.Line(recentPrices "MSFT", Name="Microsoft")])

Solution

  • I'd suggest you substituting your data generator function with something simpler and achieving correct plotting with this mockup first. For example, the following script:

    #load @"<your path here>\Fsharp.Charting.fsx"
    open System
    open FSharp.Charting
    
    let rand = System.Random
    let recentPricesMock symbol =
        [for i in 1..12 -> DateTime(2012,i,1),rand.Next(100)]
    Chart.Combine (
        [ Chart.Line(recentPricesMock "AAPL", Name="Apple")
          Chart.Line(recentPricesMock "MSFT", Name="Microsoft")])
    

    must plot combined mockup chart without any problems, as it does on my local box. From here you may drill down for the cause of original problem comparing your recentPrices with recentPricesMock.

    EDIT: after getting to the full problematic source code I can point out two problems there that, as I was expecting, are in your choice of data rather, than in charting per se:

    First, your definition of recentPrices converts dates into sequential day of year (row.Date.DayOfYear), so transition from 2012 into 2013 messes up your data and, consequently, charts. If you want to preserve your current functionality then it makes sense to redefine recentPrices as below

    let recentPrices symbol =
        let data = stockData symbol (DateTime(2012,1,1)) DateTime.Now
        [ for row in data.Data -> row.Date, row.Close ]
    

    Second, you chose a pair of stocks that doesn't scale well being combined on the single chart (AAPL in high hundreds $$, while MSFT in low tens $$), which adds to repetition of data points from first problem. After changing in your code AAPL to YHOO in addition to the recentPrices definition change described above

    Chart.Combine ([
                Chart.Line(recentPrices "YHOO", Name="Yahoo")
                Chart.Line(recentPrices "MSFT", Name="Microsoft")
                ])
    

    yields a beautiful smooth chart combo: combochart