Создание графика или графика из консольного приложения C# с использованием Matlab?
Если у меня есть двумерный массив в C#, как бы я отобразил содержимое этого массива в Matlab в виде двумерного графика? Я после метода расширения, т.е.
my2DArray.PlotInMatlab();
1 ответ
Я получил это работает хорошо в конце концов. Вот пример графика, сгенерированного консольным приложением.NET 4.0 C#, которое вызывает файл Matlab .m:
Приятно то, что мы можем использовать всю мощь Matlab для рисования графиков, используя всего несколько строк.NET.
Как это сделать в.NET:
Создайте новое консольное приложение.NET для C# в Visual Studio 2010 и измените его на.NET 4.0 (щелкните проект правой кнопкой мыши, выберите "Свойства").
.NET Main ():
using System; using System.Diagnostics; namespace MyPlotGraphUsingMatlabRuntimes { /// <summary> /// Display a graph in Matlab, from a .NET console app. /// </summary> class Program { static void Main(string[] args) { var x = new double[100]; var y = new double[100]; for (int i = 0; i < 100; i++) { x[i] = i; y[i] = 2 ^ i; } MyHelper.MyMatlab.MyGraph2D(x,y); Console.Write("[any key to exit]"); Console.ReadKey(); } } }
Класс.NET, который предоставляет методы расширения для взаимодействия с Matlab (назовите файл
MyMatlab.cs
).using System; using System.Collections.Generic; using MathWorks.MATLAB.NET.Arrays; namespace MyHelper { /// <summary> /// Collection of chained classes to make Matlab access easier. /// </summary> public static class MyMatlab { /// <summary> /// Returns a double in a format that can be passed into Matlab. /// </summary> /// <param name="toMatlab">Double to convert into a form we can pass into Matlab.</param> /// <returns>A double in Matlab format.</returns> public static MWNumericArray MyToMatlab(this double toMatlab) { return new MWNumericArray(toMatlab); } /// <summary> /// Converts an array that contains a single Matlab return parameter back into a .NET double. /// </summary> /// <param name="toDouble">MWArray variable, returned from Matlab code.</param> /// <returns>.NET double.</returns> public static double MyToDouble(this MWArray toDouble) { var matNumericArray = (MWNumericArray)toDouble; return matNumericArray.ToScalarDouble(); } /// <summary> /// Converts an array that contains multiple Matlab return parameters back into a list of .NET doubles. /// </summary> /// <param name="toList">MWArray variable, returned from Matlab code.</param> /// <returns>List of .NET doubles.</returns> public static List<double> MyToDoubleList(this MWArray toList) { var matNumericArray = toList; var netArray = (MWNumericArray)matNumericArray.ToArray(); var result = new List<double>(); // Console.Write("{0}", netArray[1]); for (int i = 1; i <= netArray.NumberOfElements; i++) // Matlab arrays are 1-based, thus the odd indexing. { result.Add(netArray[i].ToScalarDouble()); } return result; } /// <summary> /// Converts an array that contains multiple Matlab return parameters back into a list of .NET ints. /// </summary> /// <param name="toList">MWArray variable, returned from Matlab code.</param> /// <returns>List of .NET ints.</returns> public static List<int> MyToMWNumericArray(this MWArray toList) { var matNumericArray = toList; var netArray = (MWNumericArray)matNumericArray.ToArray(); var result = new List<int>(); // Console.Write("{0}", netArray[1]); for (int i = 1; i <= netArray.NumberOfElements; i++) // Matlab arrays are 1-based, thus the odd indexing. { result.Add(netArray[i].ToScalarInteger()); } return result; } /// <summary> /// Converts an int[] array into a Matlab parameters. /// </summary> /// <param name="intArray">MWArray variable, returned from Matlab code.</param> /// <returns>List of .NET ints.</returns> public static MWNumericArray MyToMWNumericArray(this int[] intArray) { return new MWNumericArray(1, intArray.Length, intArray); // rows, columns int[] realData } /// <summary> /// Converts an double[] array into parameter for a Matlab call. /// </summary> /// <param name="arrayOfDoubles">Array of doubles.</param> /// <returns>MWNumericArray suitable for passing into a Matlab call.</returns> public static MWNumericArray MyToMWNumericArray(this double[] arrayOfDoubles) { return new MWNumericArray(1, arrayOfDoubles.Length, arrayOfDoubles); // rows, columns int[] realData } /// <summary> /// Converts an List of doubles into a parameter for a Matlab call. /// </summary> /// <param name="listOfDoubles">List of doubles.</param> /// <returns>MWNumericArray suitable for passing into a Matlab call.</returns> public static MWNumericArray MyToMWNumericArray(this List<double> listOfDoubles) { return new MWNumericArray(1, listOfDoubles.Count, listOfDoubles.ToArray()); // rows, columns int[] realData } /// <summary> /// Converts a list of some type into an array of the same type. /// </summary> /// <param name="toArray">List of some type.</param> /// <returns>Array of some type.</returns> public static T[] MyToArray<T>(this List<T> toArray) { var copy = new T[toArray.Count]; for (int i = 0; i < toArray.Count; i++) { copy[i] = toArray[i]; } return copy; } static private readonly MatlabGraph.Graph MatlabInstance = new MatlabGraph.Graph(); /// <summary> /// Plot a 2D graph. /// </summary> /// <param name="x">Array of doubles, x axis.</param> /// <param name="y">Array of doubles, y axis.</param> /// <param name="title">Title of plot.</param> /// <param name="xaxis">X axis label.</param> /// <param name="yaxis">Y axis label.</param> static public void MyGraph2D(List<double> x, List<double> y, string title = "title", string xaxis = "xaxis", string yaxis = "yaxis") { MatlabInstance.Graph2D(x.MyToMWNumericArray(), y.MyToMWNumericArray(), title, xaxis, yaxis); } /// <summary> /// Plot a 2D graph. /// </summary> /// <param name="x">Array of doubles, x axis.</param> /// <param name="y">Array of doubles, y axis.</param> /// <param name="title">Title of plot.</param> /// <param name="xaxis">X axis label.</param> /// <param name="yaxis">Y axis label.</param> static public void MyGraph2D(double[] x, double[] y, string title = "title", string xaxis = "xaxis", string yaxis = "yaxis") { MatlabInstance.Graph2D(x.MyToMWNumericArray(), y.MyToMWNumericArray(), title, xaxis, yaxis); } /// <summary> /// Unit test for this class. Displays a graph using Matlab. /// </summary> static public void Unit() { { var x = new double[100]; var y = new double[100]; for (int i = 0; i < 100; i++) { x[i] = i; y[i] = Math.Sin(i); } MyGraph2D(x, y); } { var x = new double[100]; var y = new double[100]; for (int i = 0; i < 100; i++) { x[i] = i; y[i] = 2 ^ i; } MyGraph2D(x, y); } } } }
Далее мы экспортируем файл.m в сборку.NET. Я использовал Matlab 2010a (это будет работать и для 2010b). Используйте Matlab, 32-разрядная версия (32-разрядная или 64-разрядная версия отображается на заставке при запуске Matlab).
Следующий код Matlab отображает график. Сохранить как
Graph2D.m
,function Graph2D (x,y, titleTop, labelX, labelY) % Create figure myNewFigure = figure; plot(x,y) title({titleTop}); xlabel({labelX}); ylabel({labelY});
Проверьте это в Matlab, набрав в консоли следующее (не забудьте изменить
Current Folder
на панели инструментов Matlab в тот же каталог, что иGraph2D.m
):x = 0:.2:20; y = sin(x)./sqrt(x+1); Graph2D(x,y,'myTitle', 'my x-axis', 'my y-axis')
В инструменте развертывания Matlab добавьте класс
Graph
и добавьте файлGraph2D.m
, затем упакуйте его вMatlabGraph.dll
(измените имя компонента наMatlabGraph
в настройках это определяет имя сгенерированного.dll).В своем проекте.NET добавьте ссылку на
MatlabGraph.dll
(.NET .dll, с которой мы только что скомпилировалиGraph2D.m
). Это будет32-bit
если его скомпилировать с32-bit
выпуск Matlab.- В своем проекте.NET добавьте ссылку на 32-битную версию
MWArray.dll
, Вы можете найти это, выполнив поиск в каталоге установки Matlab. - Опять же, убедитесь, что все либо последовательно
32-bit
или последовательно64-bit
,- Если вы выбираете
32-bit
ваше приложение.NET должно быть скомпилировано дляx32
, вы должны использовать32-bit
версия Matlab (покажет32-bit
в заставке), чтобы экспортировать.NET .dll, и вы должны импортировать32-bit
версияMWArray.dll
в ваш.NET проект. - Если вы выбираете
64-bit
, скомпилируйте ваше приложение.NET вAll CPU
, вы должны использовать64-bit
версия Matlab (покажет64-bit
в заставке), чтобы экспортировать.NET .dll, и вы должны импортировать64-bit
версияMWArray.dll
в ваш.NET проект.
- Если вы выбираете
- Запустите приложение.NET, и оно отобразит приведенный выше график, вызвав среды выполнения Matlab.
- Если вы хотите развернуть его на новом ПК, вам нужно установить на этом ПК среду выполнения.NET (это бесплатно).
- Хорошая вещь в этом заключается в том, что вы можете настроить графики в Matlab для вашего сердца, используя всю мощь Matlab. Вы можете сделать трехмерные графики: создать новую фигуру в Matlab, используя
File..New..Figure
, настройте его, используяInsert
, а затем сгенерируйте код.m, используяFile..Generate M file
, Совершенно очевидно, что делают строки во вновь созданном файле.m, вы можете скопировать их в свой оригиналGraph2D.m
файл, затем восстановитьMatlabGraph.dll
, Например, добавление заголовка к рисунку добавляет строкуtitle({'My new title});
в автоматически сгенерированный файл.m. - Если есть какой-либо интерес, я могу предоставить полный пример проекта C# в.NET.