Создание графика или графика из консольного приложения C# с использованием Matlab?

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

my2DArray.PlotInMatlab();

1 ответ

Решение

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

Приятно то, что мы можем использовать всю мощь Matlab для рисования графиков, используя всего несколько строк.NET.

Как это сделать в.NET:

  1. Создайте новое консольное приложение.NET для C# в Visual Studio 2010 и измените его на.NET 4.0 (щелкните проект правой кнопкой мыши, выберите "Свойства").

    1. .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();
              }
          }
      }
      
    2. Класс.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);
                  }
              }
          }
      }
      
  2. Далее мы экспортируем файл.m в сборку.NET. Я использовал Matlab 2010a (это будет работать и для 2010b). Используйте Matlab, 32-разрядная версия (32-разрядная или 64-разрядная версия отображается на заставке при запуске Matlab).

    1. Следующий код Matlab отображает график. Сохранить как Graph2D.m,

      function Graph2D (x,y, titleTop, labelX, labelY)
      
      % Create figure
      myNewFigure = figure;
      
      plot(x,y)
      
      title({titleTop});
      xlabel({labelX});
      ylabel({labelY});
      
    2. Проверьте это в 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')
      
    3. В инструменте развертывания Matlab добавьте класс Graph и добавьте файл Graph2D.m, затем упакуйте его в MatlabGraph.dll (измените имя компонента на MatlabGraph в настройках это определяет имя сгенерированного.dll).

    4. В своем проекте.NET добавьте ссылку на MatlabGraph.dll (.NET .dll, с которой мы только что скомпилировали Graph2D.m). Это будет 32-bit если его скомпилировать с 32-bit выпуск Matlab.

    5. В своем проекте.NET добавьте ссылку на 32-битную версию MWArray.dll, Вы можете найти это, выполнив поиск в каталоге установки Matlab.
    6. Опять же, убедитесь, что все либо последовательно 32-bitили последовательно 64-bit,
      1. Если вы выбираете 32-bit ваше приложение.NET должно быть скомпилировано для x32, вы должны использовать 32-bit версия Matlab (покажет 32-bit в заставке), чтобы экспортировать.NET .dll, и вы должны импортировать 32-bit версия MWArray.dll в ваш.NET проект.
      2. Если вы выбираете 64-bit, скомпилируйте ваше приложение.NET в All CPU, вы должны использовать 64-bit версия Matlab (покажет 64-bit в заставке), чтобы экспортировать.NET .dll, и вы должны импортировать 64-bit версия MWArray.dll в ваш.NET проект.
    7. Запустите приложение.NET, и оно отобразит приведенный выше график, вызвав среды выполнения Matlab.
  3. Если вы хотите развернуть его на новом ПК, вам нужно установить на этом ПК среду выполнения.NET (это бесплатно).
  4. Хорошая вещь в этом заключается в том, что вы можете настроить графики в Matlab для вашего сердца, используя всю мощь Matlab. Вы можете сделать трехмерные графики: создать новую фигуру в Matlab, используя File..New..Figure, настройте его, используя Insert, а затем сгенерируйте код.m, используя File..Generate M file, Совершенно очевидно, что делают строки во вновь созданном файле.m, вы можете скопировать их в свой оригинал Graph2D.m файл, затем восстановить MatlabGraph.dll, Например, добавление заголовка к рисунку добавляет строку title({'My new title}); в автоматически сгенерированный файл.m.
  5. Если есть какой-либо интерес, я могу предоставить полный пример проекта C# в.NET.
Другие вопросы по тегам