How to: Create Line and Point Charts
Applies to: Functional Programming
Published: January 2010
This topic contains the following sections.
Summary: This article shows how to create line and point charts in F#. The example draws a graph of a function, creates a scatter plot and draws a 2D spline defined by a function.
This article is associated with Real World Functional Programming: With Examples in F# and C# by Tomas Petricek with Jon Skeet from Manning Publications (ISBN 9781933988924, copyright Manning Publications 2009, all rights reserved). No part of these chapters may be reproduced, stored in a retrieval system, or transmitted in any form or by any means—electronic, electrostatic, mechanical, photocopying, recording, or otherwise—without the prior written permission of the publisher, except in the case of brief quotations embodied in critical articles or reviews.
This article looks at how to create line and point charts from F#. It presents two versions of the example. The first one uses the FSharpChart library that is available as a free download and the second uses the .NET Chart Controls directly. For more information about loading the two libraries from F#, refer to the section at the end of the page.
This example demonstrates how to draw the graph of a simple mathematical function (such as sin(x), x2, or similar). This can be done by generating a collection containing Y values of the function. The article also shows how to draw a scatter plot from a collection of X and Y values and how to draw a 2D curve. An example of a curve drawn using a line chart is shown in Figure 1.
A line or a point chart can be created using the FSharpChart.Line and FSharpChart.Point functions. When generating a very large number of points or lines, it is better to use FSharpChart.FastLine and FSharpChart.FastPoint. These are special types of charts that do not support as many visual features, but are more efficient.
All functions are overloaded and can be called with various types of parameters. When called with a list containing just Y values, the chart automatically uses the sequence 1, 2, 3… for the X values. Alternatively, it is possible to provide a list containing both X and Y values as a tuple, which gives a way to draw 2D curves and scatter plots as well. Here are three examples:
// Drawing graph of a 'square' function FSharpChart.Line [ for x in 1.0 .. 100.0 -> x ** 2.0 ] // Generates 2D curve using list of tuples [ for i in 0.0 .. 0.02 .. 2.0 * Math.PI -> sin i, cos i * sin i ] |> FSharpChart.FastLine // Draw scatter plot using separate lists for X and Y coordinates let rnd = new Random() FSharpChart.FastPoint ( [ for i in 0 .. 1000 -> rnd.NextDouble() ], [ for i in 0 .. 1000 -> rnd.NextDouble() ] )
When using F# Interactive, each of these examples needs to be evaluated separately. This way, F# Interactive invokes a handler that automatically shows the created chart.
The first example calls the FSharpChart.Line function with a list of Y values as the only argument. The snippet generates values of a simple function, f(x)=x^2. The values of the function are generated for x ranging from 1 to 100, so the X coordinate doesn’t have to be specified explicitly explicitly.
The second example generates a list containing both X and Y values. It uses a sequence expression ranging from 0 to 2π with a step size 0.02. This produces a large number of points, so the snippet uses the FSharpChart.FastLine function to draw the chart. When using a single list as the data source, it is also possible to elegantly use pipelining (|> operator).
Finally, the last example shows how to generate a scatter plot. It uses two lists to specify the X- and Y-coordinates of the points separately. However, the same chart can be created using just a single collection yielding tuples.
This sections shows how to create similar charts using .NET Chart Controls. The following example demonstrates how to create the 2D curve shown in Figure 1. The snippet generates points of the chart as a single list of tuples. When constructing the chart, the type of the chart can be specified using the ChartType property of the Series object. To create a line chart, the property should be set to SeriesChartType.Line (the other options are SeriesChartType.Point for a point chart, and SeriesChartType.FastLine, or SeriesChartType.FastPoint for simpler, but more efficient versions of the two charts).
let data = [ for i in 0.0 .. 0.02 .. 2.0 * Math.PI -> sin i, cos i * sin i ] // Create a chart containing a default area and show it on a form let chart = new Chart(Dock = DockStyle.Fill) let form = new Form(Visible = true, Width = 700, Height = 500) chart.ChartAreas.Add(new ChartArea("MainArea")) form.Controls.Add(chart) // Create series and add it to the chart let series = new Series(ChartType = SeriesChartType.Line) chart.Series.Add(series) // Add data to the series in a loop for x, y in data do series.Points.AddXY(x, y) |> ignore
After initializing the list, the snippet construct the user interface elements. The snippet displays the chart in a new window. It creates a Form, the Chart control, and then adds the control to the form. Then it creates a new series and specifies the type of the chart that it represents.
In this example, data points are added to the data series one by one using the AddXY method of the Points collection. The snippet could call this method when generating the data, but separating the generation and visualization makes the snippet clearer. The method can be also called later (after the chart is displayed) to add new points as they become available.
This section reviews the prerequisites needed to run the two examples discussed above. Both of the approaches build on top of the Microsoft Charting Library, which is available as part of the .NET 4.0 framework and can be downloaded separately for .NET 3.5.
Using the FSharpChart Library
The F# Charting library is available as a free download. The easiest way to use the library from F# Interactive is to download the library source code (FSharpChart.fsx) and load it in F# Interactive using the #load command:
This snippet opens the namespaces that is needed when working with the library (the above examples assume these namespaces are opened). The namespace Samples.Charting contains the F# charting functionality. After writing the above lines, charts can be created using the FSharpChart type.
When loading the FSharpChart library in F# Interactive using the FSharpChart.fsx script file, it is not necessary to explicitly load the .NET Chart Controls assembly (System.Windows.Forms.DataVisualization.dll), because it is automatically referenced by the library script.
When creating a chart in a Windows Forms application, it is easier to reference the compiled version of the FSharpChart library (which can be downloaded as part of the sample source code at the end of the article). The library name is Samples.Charting.dll and it needs to be referenced together with the .NET Chart Controls assembly System.Windows.Forms.DataVisualization.dll. This can be done using the "Add Reference" command in Solution Explorer in Visual Studio.
Using .NET Chart Controls
When creating a chart from an F# script using F# Interactive, the script needs to reference the Microsoft Chart Controls assembly for Windows Forms. This is done by adding the following lines to an F# Script File (e.g. Script.fsx):
#r "System.Windows.Forms.DataVisualization.dll" open System open System.Drawing open System.Windows.Forms open System.Windows.Forms.DataVisualization.Charting
The code snippets in the first sections don't include these import declarations. In order to compile the code (as a standalone application), the following step is needed as well:
When creating a chart in a Windows Forms application or a library, the project needs to reference the .NET Chart Controls assembly using the "Add Reference" command in Solution Explorer in Visual Studio. The name of the assembly is System.Windows.Forms.DataVisualization.dll.
This article demonstrates how to use the FSharpChart library and .NET Chart Controls to create charts. For more information about charting in F# visit the following page:
This article is based on Real World Functional Programming: With Examples in F# and C#. Book chapters related to the content of this article are:
Book Chapter 4: “Exploring F# and .NET libraries by example” demonstrates how to create a simple charting application from scratch. This chapter is useful for learning F# programming when focusing on working with data.
Book Chapter 12: “Sequence expressions and alternative workflows” explains how to work with in-memory data sets in F# using sequence expressions and higher-order functions.
Book Chapter 13: “Asynchronous and data-driven programming” shows how to use asynchronous workflows to obtain data from the internet, how to convert data to a structured format, and how to chart it using Excel.
To download the code snippets shown in this article, go to http://code.msdn.microsoft.com/Chapter-6-Visualizing-Data-c68a2296