Создание графика или графика из консольного приложения C # с использованием Matlab? - PullRequest
6 голосов
/ 05 октября 2011

Если у меня есть двумерный массив в C #, как бы я отобразил содержимое этого массива в Matlab в виде двумерного графика?Я за метод расширения, то есть

my2DArray.PlotInMatlab();

1 Ответ

9 голосов
/ 08 октября 2011

В конце концов, у меня все получилось.Вот примерный график, сгенерированный консольным приложением .NET 4.0 C #, который вызывает файл Matlab .m:

enter image description here

Приятно то, что мы можем использовать все возможности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, если он скомпилирован с выпуском Matlab 32-bit.

В вашем проекте .NET добавьте ссылку на 32-битную версию MWArray.dll.Вы можете найти это, выполнив поиск в каталоге установки Matlab. Опять же, убедитесь, что все либо последовательно 32-bit, либо последовательно 64-bit. Если вы выберете 32-bit, ваше приложение .NET должно быть скомпилировано для x32, вы должны использовать версию Matlab 32-bit (на заставке будет отображаться 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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...