capsule.adrianhesketh.com
.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 xSeries, IEnumerable ySeries)
{
model.AddScatterSeries(xSeries, ySeries, OxyColors.Automatic);
}
public static void AddScatterSeries(this PlotModel model, IEnumerable xSeries, IEnumerable 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 xSeries, IEnumerable ySeries)
{
model.AddLineSeries(xSeries, ySeries, OxyColors.Automatic);
}
public static void AddLineSeries(this PlotModel model, IEnumerable xSeries, IEnumerable ySeries)
{
model.AddLineSeries(xSeries, ySeries, OxyColors.Automatic);
}
public static void AddLineSeries(this PlotModel model, IEnumerable xSeries, IEnumerable 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 xSeries, IEnumerable 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 xLabels, IEnumerable ySeries)
{
model.AddColumnSeries(xLabels, ySeries, OxyColors.Automatic);
}
public static void AddColumnSeries(this PlotModel model, IEnumerable xLabels, IEnumerable 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);
}
}