使用Matlab从C#控制台应用程序创建图形或绘图?

如果我在C#中有一个二维数组,我如何在Matlab中绘制这个数组的内容,作为二维图? 我正在使用扩展方法,即

my2DArray.PlotInMatlab(); 

我最终搞定了这个。 下面是一个示例图,由调用Matlab .m文件的.NET 4.0 C#控制台应用程序生成:

在此处输入图像描述

好消息是我们可以使用Matlab的所有function来绘制图形,只需几行.NET。

如何在.NET中执行此操作:

  1. 在Visual Studio 2010中为C#创建一个新的.NET控制台应用程序,并将其更改为.NET 4.0(右键单击该项目,选择“属性”)。

    1. .NET Main():

       using System; using System.Diagnostics; namespace MyPlotGraphUsingMatlabRuntimes { ///  /// Display a graph in Matlab, from a .NET console app. ///  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 { ///  /// Collection of chained classes to make Matlab access easier. ///  public static class MyMatlab { ///  /// Returns a double in a format that can be passed into Matlab. ///  /// Double to convert into a form we can pass into Matlab. /// A double in Matlab format. public static MWNumericArray MyToMatlab(this double toMatlab) { return new MWNumericArray(toMatlab); } ///  /// Converts an array that contains a single Matlab return parameter back into a .NET double. ///  /// MWArray variable, returned from Matlab code. /// .NET double. public static double MyToDouble(this MWArray toDouble) { var matNumericArray = (MWNumericArray)toDouble; return matNumericArray.ToScalarDouble(); } ///  /// Converts an array that contains multiple Matlab return parameters back into a list of .NET doubles. ///  /// MWArray variable, returned from Matlab code. /// List of .NET doubles. public static List MyToDoubleList(this MWArray toList) { var matNumericArray = toList; var netArray = (MWNumericArray)matNumericArray.ToArray(); var result = new List(); // 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; } ///  /// Converts an array that contains multiple Matlab return parameters back into a list of .NET ints. ///  /// MWArray variable, returned from Matlab code. /// List of .NET ints. public static List MyToMWNumericArray(this MWArray toList) { var matNumericArray = toList; var netArray = (MWNumericArray)matNumericArray.ToArray(); var result = new List(); // 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; } ///  /// Converts an int[] array into a Matlab parameters. ///  /// MWArray variable, returned from Matlab code. /// List of .NET ints. public static MWNumericArray MyToMWNumericArray(this int[] intArray) { return new MWNumericArray(1, intArray.Length, intArray); // rows, columns int[] realData } ///  /// Converts an double[] array into parameter for a Matlab call. ///  /// Array of doubles. /// MWNumericArray suitable for passing into a Matlab call. public static MWNumericArray MyToMWNumericArray(this double[] arrayOfDoubles) { return new MWNumericArray(1, arrayOfDoubles.Length, arrayOfDoubles); // rows, columns int[] realData } ///  /// Converts an List of doubles into a parameter for a Matlab call. ///  /// List of doubles. /// MWNumericArray suitable for passing into a Matlab call. public static MWNumericArray MyToMWNumericArray(this List listOfDoubles) { return new MWNumericArray(1, listOfDoubles.Count, listOfDoubles.ToArray()); // rows, columns int[] realData } ///  /// Converts a list of some type into an array of the same type. ///  /// List of some type. /// Array of some type. public static T[] MyToArray(this List 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(); ///  /// Plot a 2D graph. ///  /// Array of doubles, x axis. /// Array of doubles, y axis. /// Title of plot. /// X axis label. /// Y axis label. static public void MyGraph2D(List x, List y, string title = "title", string xaxis = "xaxis", string yaxis = "yaxis") { MatlabInstance.Graph2D(x.MyToMWNumericArray(), y.MyToMWNumericArray(), title, xaxis, yaxis); } ///  /// Plot a 2D graph. ///  /// Array of doubles, x axis. /// Array of doubles, y axis. /// Title of plot. /// X axis label. /// Y axis label. 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); } ///  /// Unit test for this class. Displays a graph using Matlab. ///  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)。 使用32位版本的Matlab(当Matlab启动时,在启动画面中显示32位或64位)。

    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中进行测试(确保将Matlab工具栏中的Current Folder更改为与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 (我们刚刚从Graph2D.m编译的.NET .dll)的Graph2D.m 。 如果使用32-bit版本的Matlab编译,这将是32-bit

    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. 如果要将其部署到新PC,则必须在此PC上安装.NET运行时(这些都是免版税的)。
  4. 关于这一点的好处是你可以使用Matlab的所有function在Matlab中自定义图形中的图形。 你可以做3-D图:使用File..New..Figure在Matlab中创建一个新图,使用Insert自定义它,然后使用File..Generate M file生成.m代码。 很明显新生成的.m文件中的行是什么,你可以将它们复制到原始的Graph2D.m文件中,然后重新生成MatlabGraph.dll 。 例如,为图形添加title({'My new title});会添加一个行title({'My new title}); 到自动生成的.m文件。
  5. 如果有兴趣,我可以在.NET中提供完整的C#示例项目。