Plotting in C# (Part 4 - ScottPlot)
Amir Doosti
Software Engineer | 20+ Years of Expertise | .NET, Industrial Automation with Beckhoff, Microservices Architecture
ScottPlot is an open-source, .NET-based charting library designed for creating high-performance, interactive plots in applications like WinForms, WPF, and Console apps. Its simplicity, lightweight design, and focus on performance make it a great choice for developers working with scientific or large-scale data visualizations.
Some characteristics of ScottPlot are:
- Ease of Use: Simple API to generate plots with minimal setup.
- High Performance: Handles large datasets efficiently (e.g., millions of data points).
- Customization: Fully customizable charts (colors, markers, titles, legends, axes, etc.).
- Interactivity: Built-in support for zooming, panning, and interacting with plots.
- Live/Streaming Data: Real-time data plotting capabilities.
Setting up ScottPlot in a WinForms application
Setting up ScottPlot in a WinForms application is straightforward. Here’s how you can do it:
- Install ScottPlot via NuGet by searching for ScottPlot.WinForms and then installing the backage
- Add a ScottPlot Control to Your Form: Open a WinForm and add FormsPlot to your form
- Setting up the plot in code: After adding the FormsPlot control, you can configure it in the code-behind file.
using System;
using System.Windows.Forms;
namespace ScottPlotWinFormsExample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// Generate some sample data
double[] xs = DataGen.Consecutive(100); // X data
double[] ys = DataGen.Sin(100); // Y data
// Add a scatter plot
formsPlot1.Plot.AddScatter(xs, ys);
// Add titles and labels
formsPlot1.Plot.Title("Sample Chart");
formsPlot1.Plot.XLabel("X-Axis");
formsPlot1.Plot.YLabel("Y-Axis");
// Refresh the plot to display it
formsPlot1.Refresh();
}
}
}
ScottPlot versions
The latest version of ScottPlot at the time of writing this article is 5.0.46. Version 5 and higher is not fully compatible with lower versions. ScottPlot has evolved significantly, with v5.x introducing a new architecture and new features compared to the v4.x series.?
Here are some of the most important features of v5.x compare to v4.x:
Redesigned API:
- More intuitive and consistent.
- Fluent interface for chaining methods.
- Enhanced code readability and maintainability.
Improved Performance:
- Optimized for large datasets.
- Handles live/streaming data more efficiently.
Better Interactivity:
- More robust zooming, panning, and interaction features.
- Enhanced event system for handling clicks, hovers, and drag events.
Legend Improvements:
- Highly customizable legend positioning and formatting.
- Clickable legends to toggle series visibility.
Rendering Pipeline:
- Fully rewritten for smoother animations and better scaling across high-DPI monitors.
New Features:
- Plot styling improvements.
- Simplified handling of axes and layout management.
- Customizable tick marks and grid styles.
Showing and Formatting the Legend
Show Legend: The legend is automatically enabled if multiple plots are added with labels.
Customize Legend: The legend can easily customized.
formsPlot1.Plot.Legend(location: ScottPlot.Alignment.UpperRight);
formsPlot1.Plot.Legend(fontSize: 14, bold: true);
formsPlot1.Refresh();
Chart Customization
Adding a Title
领英推è
formsPlot1.Plot.Title("Sample Chart", size: 20);
formsPlot1.Plot.XLabel("X-Axis", size: 16);
formsPlot1.Plot.YLabel("Y-Axis", size: 16);
formsPlot1.Refresh();
Customizing Colors and Style
var scatter = formsPlot1.Plot.AddScatter(xs, ys);
scatter.Color = System.Drawing.Color.Red;
scatter.LineWidth = 2;
formsPlot1.Plot.Style(ScottPlot.Style.Light1); // Predefined styles
formsPlot1.Refresh();
Working with Axes
Format Axes
formsPlot1.Plot.SetAxisLimits(xMin: 0, xMax: 10, yMin: -5, yMax: 5);
formsPlot1.Plot.XAxis.ManualTickSpacing(1); // Set custom tick spacing
formsPlot1.Plot.XAxis.TickLabelStyle(fontSize: 14);
formsPlot1.Refresh();
Horizontal Time Axis
var dates = Enumerable.Range(0, 10).Select(i => DateTime.Now.AddDays(i)).ToArray();
double[] xs = dates.Select(x => x.ToOADate()).ToArray();
double[] ys = new double[xs.Length]; // Some Y data
formsPlot1.Plot.AddScatter(xs, ys);
formsPlot1.Plot.XAxis.DateTimeFormat(true); // Enable date formatting
formsPlot1.Refresh();
Handling Large Data
ScottPlot provides tools to handle large datasets (e.g., decimation).
Using SignalPlot for Large Data:
var signal = formsPlot1.Plot.AddSignal(data);
formsPlot1.Refresh();
Real-Time/Streaming Data
var scatter = formsPlot1.Plot.AddScatter(xs, ys);
// Updating in a Timer
Timer timer = new Timer { Interval = 100 }; // Refresh every 100ms
timer.Tick += (s, e) =>
{
xs = xs.Skip(1).Concat(new[] { xs.Last() + 1 }).ToArray(); // Shift Xs
ys = ys.Skip(1).Concat(new[] { Random.Shared.NextDouble() }).ToArray(); // Shift Ys
scatter.Update(xs, ys);
formsPlot1.Refresh();
};
timer.Start();
Interactions (Zoom, Pan, Toggle Series, Get Data)
Zoom and Pan: Enabled by default in WinForms via mouse scroll and drag.
Turn On/Off Series
scatter.IsVisible = false; // Hide series
formsPlot1.Refresh();
Get Point Value by Mouse
formsPlot1.MouseMove += (s, e) =>
{
(double mouseX, double mouseY) = formsPlot1.GetMouseCoordinates();
lblCoords.Text = $"Mouse: {mouseX}, {mouseY}";
};
Annotations
formsPlot1.Plot.AddText("Hello", x: 5, y: 5);
formsPlot1.Refresh();
Comparison between LiveCharts2, OxyPlot and ScottPlot
Here's a detailed comparison of LiveCharts2, OxyPlot, and ScottPlot based on their latest versions. Note that these are just my personal idea:
Conclusion
ScottPlot is an excellent choice for developers looking for a lightweight, high-performance charting solution, especially for scientific or engineering applications. It’s particularly strong when handling large datasets or real-time data, I’ve personally tested it for more than 2 million points and it still worked perfectly. Maybe some features are still not implemented or need improvement but, ScottPlot remains a highly capable and efficient tool for most charting needs.
#plot #scottplot #csharp #dotnet