← Home

.Net Graphs on Linux - OxyPlot

This week I was attempting to graph some data at home using MonoDevelop (I’ve been using Linux as my primary desktop operating system at home for 5 years now), where the Windows Forms chart component isn’t available.

I was already fed up with sending LinqPad scripts over to colleagues and having to explain how to install Sho and IronPython, so I had a quick look around for alternatives.

OxyPlot was up and running in a few minutes and has a great selection of NuGet packages for different platforms, with no installation required. The API is also fairly simple and it worked perfectly on my Linux setup.

Here’s OxyPlot in action:

http://share.linqpad.net/aiuvnc.linq

The only think I didn’t like is that each different type of series (scatter, line, column) has to be constructed individually, so if you want to try out different displays, you have a few lines to update, whereas on Sho, you only need to change from AddBarSeries to AddSeries to switch, so I made some extension methods. Maybe they’ll be useful for you.

void Main()	
{
	var model = new PlotModel { Title = "Test" };
	
	var xseries = new double[] { 1, 2, 3 };
	var yseries1 = new double[] { 1, 2, 3 };
	var yseries2 = new double[] { 0.5, 1, 1.5 };
	
	model.AddScatterSeries(xseries, yseries1, OxyColors.Red);
	model.AddHighlightedPoint(2.5, 2.5, OxyColors.Blue);
	model.AddLineSeries(xseries, yseries2);
	
	ShowChart(model);
}

public static void ShowChart(PlotModel model)
{
	var chart = new PlotView();
	chart.Model = model;
	chart.Dump();
}
public static class OxyPlotExtensions
{
   public static void AddScatterSeries(this PlotModel model, IEnumerable<double> xSeries, IEnumerable<double> ySeries)
   {
       model.AddScatterSeries(xSeries, ySeries, OxyColors.Automatic);
   }

   public static void AddScatterSeries(this PlotModel model, IEnumerable<double> xSeries, IEnumerable<double> ySeries, OxyColor color)
   {
       var scatterSeries = new ScatterSeries()
       {
           MarkerFill = color,
           MarkerSize = 1,
       };

       foreach (var item in xSeries.Zip(ySeries, (x, y) => new { x, y }))
       {
           scatterSeries.Points.Add(new ScatterPoint(item.x, item.y));
       }

       model.Series.Add(scatterSeries);
   }

   public static void AddHighlightedPoint(this PlotModel model, double x, double y)
   {
       model.AddHighlightedPoint(x, y, OxyColors.Automatic);
   }

   public static void AddHighlightedPoint(this PlotModel model, double x, double y, OxyColor color)
   {
       var scatterSeries = new ScatterSeries()
       {
           MarkerFill = color,
           MarkerType = MarkerType.Triangle,
           MarkerSize = 5,
       };

       scatterSeries.Points.Add(new ScatterPoint(x, y));

       model.Series.Add(scatterSeries);
   }

   public static void AddLineSeries(this PlotModel model, IEnumerable<double> xSeries, IEnumerable<double> ySeries)
   {
       model.AddLineSeries(xSeries, ySeries, OxyColors.Automatic);
   }
   
   public static void AddLineSeries(this PlotModel model, IEnumerable<DateTime> xSeries, IEnumerable<double> ySeries)
   {
       model.AddLineSeries(xSeries, ySeries, OxyColors.Automatic);
   }

   public static void AddLineSeries(this PlotModel model, IEnumerable<DateTime> xSeries, IEnumerable<double> ySeries, OxyColor color)
   {
       model.Axes.Add(new DateTimeAxis());
       model.AddLineSeries(xSeries.Select(x => DateTimeAxis.ToDouble(x)), ySeries);
   }
   
   public static void AddLineSeries(this PlotModel model, IEnumerable<double> xSeries, IEnumerable<double> ySeries, OxyColor color)
   {
       var lineSeries = new LineSeries();

       foreach (var item in xSeries.Zip(ySeries, (x, y) => new { x, y }))
       {
           lineSeries.Points.Add(new DataPoint(item.x, item.y));
       }

       model.Series.Add(lineSeries);
   }   

   public static void AddColumnSeries(this PlotModel model, IEnumerable<string> xLabels, IEnumerable<double> ySeries)
   {
       model.AddColumnSeries(xLabels, ySeries, OxyColors.Automatic);
   }

   public static void AddColumnSeries(this PlotModel model, IEnumerable<string> xLabels, IEnumerable<double> ySeries, OxyColor color)
   {
       var axis = new CategoryAxis() { Position = AxisPosition.Bottom };
       axis.Labels.AddRange(xLabels);
       model.Axes.Add(axis);

       var columnSeries = new ColumnSeries()
       {
           FillColor = color,
       };

       columnSeries.Items.AddRange(ySeries.Select(y => new ColumnItem(y)));

       model.Series.Add(columnSeries);
   }
}