2

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?

gioaudino
  • 573
  • 8
  • 23

2 Answers2

5

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

latkin
  • 16,402
  • 1
  • 47
  • 62
  • I've opened a bug for this odd behavior: https://github.com/fslaborg/FSharp.Charting/issues/82 – latkin Jul 09 '15 at 17:34
2

As far as I know you cannot Chart.Combine charts with independent scales. However, you may stack them on each other with a different combinator, for example with Chart.Rows like in snippet below

#I @"C:\code\packages\FSharp.Charting.0.90.12"
#load "FSharp.Charting.fsx"

open FSharp.Charting
open System

let parabola = [ for x in 1.0 .. 1.0 .. 10.0 -> (x, (x ** 2.0) * 1000.0 ) ]
let curve = [ for i in 0.0 .. 0.02 .. 2.0 * Math.PI -> (sin i, cos i * sin i) ] 

Chart.Rows([Chart.Line(parabola); Chart.Line(curve)])

producing the combined chart with constituents having quite different scale:

enter image description here

Gene Belitski
  • 10,270
  • 1
  • 34
  • 54