Search code examples
f#fsharpchart

FSharpChart: two scales on same graphic


I'm using FSharpChart to print on the same graphic the moving average and the volume of a stock. The problem is that one graphic goes from 20 to 50 more or less, the other from 0 to 80 mln, so when I combine the two, one is split to the bottom and this is useless. Can I have two different scales on the Y-axis so that the two graphic "merge" correctly?


Solution

  • You can do this if you set the AxisType of one of the series to AxisType.Secondary. Of course it's then up to you to make sure axis labels, legend, etc make it clear which data maps to which scale.

    open FSharp.Charting
    open System.Windows.Forms.DataVisualization.Charting
    
    let squaresChart = [ 1 .. 100 ] |> List.map (fun n -> (n, n*n)) |> Chart.Line
    let cubesChart   = [ 1 .. 100 ] |> List.map (fun n -> (n, n*n*n)) |> Chart.Line
    
    let bad = 
        [ squaresChart 
          cubesChart ]
        |> Chart.Combine
    
    let good = 
        [ squaresChart
          cubesChart |> Chart.WithSeries.AxisType(YAxisType = AxisType.Secondary) ]
        |> Chart.Combine
    

    Bad:

    enter image description here

    Good:

    enter image description here

    This works, but in the quick testing I've done to write this answer, it appears that FSharp.Charting has some bugs whereby certain customizations are "infectious." After creating the "good" chart, the secondary axis now appears even when I don't want it:

    // secondary axis sticks around
    bad |> Chart.WithTitle(Text = "Why secondary axis?")
    
    // now the title and the secondary axis *both* stick around!
    Chart.Rows [bad; good]
    

    enter image description here enter image description here