创建从一个C#控制台应用程序图形或情节,用Matlab?控制台、应用程序、图形、情节

2023-09-02 01:45:50 作者:温柔尝尽了嘛

如果我有一个二维数组在C#中,我将如何绘制这个数组在Matlab中的内容,作为一个2-D图形?我一个扩展方法,即后我。

  my2DArray.PlotInMatlab();
 

解决方案

我得到这个工作,以及在年底。下面是一个示例图,由.N​​ET 4.0的C#控制台应用程序调用Matlab的.m文件生成的:

的好处是,我们可以用Matlab的一切权力绘制图形,使用.NET的只有几行。

如何做到这一点的。NET:

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

.NET的Main():

 使用系统;
使用System.Diagnostics程序;

命名空间MyPlotGraphUsingMatlabRuntimes
{
    ///<总结>
    ///显示在Matlab的图形,从.NET控制台应用程序。
    ///< /总结>
    类节目
    {
        静态无效的主要(字串[] args)
        {
            变种x =新的双[100];
            变种Y =新的双[100];
            的for(int i = 0; I< 100;我++){
                X [我] =我;
                Y [i] = 2 ^我;
            }
            MyHelper.MyMatlab.MyGraph2D(X,Y);
            Console.Write([任意键退出]);
            Console.ReadKey();
        }
    }
}
 
C 连接MySQL

.NET类,它提供的扩展方法做互操作到MATLAB(文件命名为 MyMatlab.cs )。

 使用系统;
使用System.Collections.Generic;
使用MathWorks.MATLAB.NET.Arrays;
命名空间MyHelper
{
    ///<总结>
    ///收藏链接类,使Matlab的访问更加容易。
    ///< /总结>
    公共静态类MyMatlab
    {
        ///<总结>
        ///返回一个双冠王可以传递到MATLAB中的格式。
        ///< /总结>
        ///< PARAM NAME =toMatlab>双转换成一种形式,我们可以传递到MATLAB< /参数>
        ///<返回>双Matlab中的格式和LT; /回报>
        公共静态MWNumericArray MyToMatlab(这双toMatlab)
        {
            返回新MWNumericArray(toMatlab);
        }
        ///<总结>
        ///包含一个Matlab的返回参数恢复成.NET双数组转换。
        ///< /总结>
        ///< PARAM NAME =toDouble> MWArray变量,在MATLAB code返回< /参数>
        ///<返回> .NET双< /回报>
        公共静态双MyToDouble(此MWArray toDouble)
        {
            VAR matNumericArray =(MWNumericArray)toDouble;
            返回matNumericArray.ToScalarDouble();
        }
        ///<总结>
        ///包含多个Matlab的返回参数返回到.NET双打的名单数组转换。
        ///< /总结>
        ///< PARAM NAME =了ToList> MWArray变量,在MATLAB code返回< /参数>
        ///<返回> .NET名单双打< /回报>
        公共静态列表<双> MyToDoubleList(此MWArray了ToList)
        {
            VAR matNumericArray =了ToList;
            变种netArray =(MWNumericArray)matNumericArray.ToArray();

            VAR的结果=新名单,其中,双>();
            // Console.Write({0},netArray [1]);
            的for(int i = 1; I< = netArray.NumberOfElements;我++)// Matlab的数组是从1开始的,因此奇数索引。
            {
                result.Add(netArray [I] .ToScalarDouble());
            }
            返回结果;
        }
        ///<总结>
        ///包含多个Matlab的返回参数返回到.NET整数列表数组转换。
        ///< /总结>
        ///< PARAM NAME =了ToList> MWArray变量,在MATLAB code返回< /参数>
        ///<返回> .NET整数的名单,其中,。/回报>
        公共静态列表< INT> MyToMWNumericArray(此MWArray了ToList)
        {
            VAR matNumericArray =了ToList;
            变种netArray =(MWNumericArray)matNumericArray.ToArray();

            VAR的结果=新名单,其中,INT>();
            // Console.Write({0},netArray [1]);
            的for(int i = 1; I< = netArray.NumberOfElements;我++)// Matlab的数组是从1开始的,因此奇数索引。
            {
                result.Add(netArray [I] .ToScalarInteger());
            }
            返回结果;
        }
        ///<总结>
        ///转换一个int []数组Matlab的参数。
        ///< /总结>
        ///< PARAM NAME =intArray>从MATLAB code MWArray变量,返回< /参数>
        ///<返回> .NET整数的名单,其中,。/回报>
        公共静态MWNumericArray MyToMWNumericArray(这INT [] intArray)
        {
            返回新MWNumericArray(1,intArray.Length,intArray); //行,列INT [] realData
        }
        ///<总结>
        ///转换的双重[]数组参数Matlab的电话。
        ///< /总结>
        ///< PARAM NAME =arrayOfDoubles>双打的阵列< /参数>
        ///<返回> MWNumericArray适合突入Matlab的调用和LT; /回报>
        公共静态MWNumericArray MyToMWNumericArray(这种双重[] arrayOfDoubles)
        {
            返回新MWNumericArray(1,arrayOfDoubles.Length,arrayOfDoubles); //行,列INT [] realData
        }
        ///<总结>
        ///双打的列表转换成一个Matlab的调用的参数。
        ///< /总结>
        ///< PARAM NAME =listOfDoubles>双打的名单,其中,。/参数>
        ///<返回> MWNumericArray适合突入Matlab的调用和LT; /回报>
        公共静态MWNumericArray MyToMWNumericArray(名单<双> listOfDoubles)
        {
            返回新MWNumericArray(1,listOfDoubles.Count,listOfDoubles.ToArray()); //行,列INT [] realData
        }
        ///<总结>
        ///某种类型的列表转换成相同类型的数组。
        ///< /总结>
        ///< PARAM NAME =的toArray>某些类型的名单,其中,/参数>
        ///<返回>有些类型的数组< /回报>
        公共静态T [] MyToArray< T>(名单< T>的toArray)
        {
            VAR复制=新T [toArray.Count]
            的for(int i = 0; I< toArray.Count;我++){
                副本[i] =的toArray [I]
            }
            返回副本;
        }
        静态专用只读MatlabGraph.Graph MatlabInstance =新MatlabGraph.Graph();
        ///<总结>
        ///绘制二维图形。
        ///< /总结>
        ///< PARAM NAME =X>双打的阵列,X轴和LT; /参数>
        ///< PARAM NAME =Y>双打的阵列,Y轴和LT; /参数>
        ///< PARAM NAME =头衔 -  GT;情节标题< /参数>
        ///< PARAM NAME =x轴> X轴标签< /参数>
        ///< PARAM NAME =Y轴> Y轴标签< /参数>
        静态公共无效MyGraph2D(名单<双> X,名单,其中,双> Y,字符串标题=标题,串x轴=x轴,串y轴=Y轴)
        {
            MatlabInstance.Graph2D(x.MyToMWNumericArray(),y.MyToMWNumericArray(),标题,X轴,Y轴);
        }
        ///<总结>
        ///绘制二维图形。
        ///< /总结>
        ///< PARAM NAME =X>双打的阵列,X轴和LT; /参数>
        ///< PARAM NAME =Y>双打的阵列,Y轴和LT; /参数>
        ///< PARAM NAME =头衔 -  GT;情节标题< /参数>
        ///< PARAM NAME =x轴> X轴标签< /参数>
        ///< PARAM NAME =Y轴> Y轴标签< /参数>
        静态公共无效MyGraph2D(双[]×,双[] Y,字符串标题=标题,串x轴=x轴,串y轴=Y轴)
        {
            MatlabInstance.Graph2D(x.MyToMWNumericArray(),y.MyToMWNumericArray(),标题,X轴,Y轴);
        }
        ///<总结>
        ///单元测试这个类。显示用Matlab的曲线图。
        ///< /总结>
        静态公共无效单位()
        {
            {
                变种x =新的双[100];
                变种Y =新的双[100];
                的for(int i = 0; I< 100;我++){
                    X [我] =我;
                    值Y [i] = Math.Sin(ⅰ);
                }
                MyGraph2D(X,Y);
            }

            {
                变种x =新的双[100];
                变种Y =新的双[100];
                的for(int i = 0; I< 100;我++){
                    X [我] =我;
                    Y [i] = 2 ^我;
                }
                MyGraph2D(X,Y);
            }
        }
    }
}
 

接下来,我们一.m文件导出到一个.NET程序集。我用Matlab的2010A(这将适用于2010年b也)。使用MATLAB,32位版本(32位或64位时,Matlab的启动显示在闪屏)。

下面Matlab的code上显示的曲线图。将其保存为 Graph2D.m

 函数Graph2D(X,Y,titleTop,labelX,labelY)

%创建数字
myNewFigure =图;

积(X,Y)

标题({titleTop});
xlabel({labelX});
ylabel({labelY});
 

测试此内Matlab的通过键入以下内容在控制台(请确保您在Matlab工具栏到同一目录更改当前文件夹 Graph2D.m ):

  X = 0:0.2:20;
Y = SIN(X)./的sqrt(x + 1);
Graph2D(X,Y,'myTitle','我的X轴,我的y轴)
 

在Matlab的部署工具,添加一个类,并添加文件 Graph2D.m ,然后将其打包成 MatlabGraph.dll (更改零部件名称 MatlabGraph 的设置,这决定了的名字.DLL生成)。

在你的.NET项目,添加引用 MatlabGraph.dll (在.NET .dll文件,我们刚刚从 Graph2D编译.M )。这将是 32位如果用 32位发布Matlab的编译。

在.NET项目,添加对32位版本的 MWArray.dll 的。您可以通过搜索Matlab的安装目录中找到这一点。 同样,确保一切都可以是一致的 32位,或持续 64位。 如果您选择 32位,你的.NET应用程序必须被编译为 32倍,您必须使用 32位版本的matlab(它会显示 32位在启动画面)导出.NET。 DLL,你必须导入 32位 MWArray.dll 到你的.NET项目。 如果您选择 64位,编译你的.NET应用程序到所有CPU ,则必须使用 64位版本的matlab(它会显示 64位在启动画面)导出.NET .dll文件,你必须导入 64位 MWArray.dll 到你的.NET项目。 运行.NET应用程序,它会显示在图形上方,通过调用Matlab的运行时间。 如果要部署这一个新的电脑,你将不得不在这台电脑上安装.NET运行时(这些都是免版税)。 有关这样做的好处是,你可以自定义在Matlab的图形你的心内容,用Matlab的一切权力。你可以做3-D图形:使用 File..New..Figure 创建Matlab的一个新的数字,使用自定义插入,然后使用生成的m code File..Generate M档。它相当明显发生了什么,在新生成的.m文件的行做的,你可以将它们复制到原始的 Graph2D.m 文件,然后重新生成 MatlabGraph。 DLL 。例如,添加标题,以图增加了一个行标题({我的新标题}); 来自动生成.m文件 如果有任何兴趣,我可以在.NET提供了完整的C#示例项目。

If I have a two dimensional array in C#, how would I plot the contents of this array in Matlab, as a 2-D graph? I'm after an extension method, i.e.

my2DArray.PlotInMatlab();

解决方案

I got this working well in the end. Here is a sample graph, generated by a .NET 4.0 C# console app that calls a Matlab .m file:

The nice thing is that we can use all the power of Matlab for drawing graphs, with only a few lines of .NET.

How to do this in .NET:

Create a new .NET console app for C# in Visual Studio 2010, and change it to .NET 4.0 (right click on the project, select "Properties").

.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 class that provides extension methods to do interop into Matlab (name the file 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);
            }
        }
    }
}

Next, we export a .m file into a .NET assembly. I used Matlab 2010a (this will work for 2010b also). Use Matlab, 32-bit version (32-bit or 64-bit is displayed in the splash screen when Matlab starts up).

The following Matlab code displays a graph. Save it as Graph2D.m.

function Graph2D (x,y, titleTop, labelX, labelY)

% Create figure
myNewFigure = figure;

plot(x,y)

title({titleTop});
xlabel({labelX});
ylabel({labelY});

Test this within Matlab by typing the following at the console (make sure you change Current Folder in the Matlab toolbar to the same directory as Graph2D.m):

x = 0:.2:20;
y = sin(x)./sqrt(x+1);
Graph2D(x,y,'myTitle', 'my x-axis', 'my y-axis')

In the Matlab deployment tool, add a class Graph , and add the file Graph2D.m , then package it into MatlabGraph.dll (change the component name to MatlabGraph in settings, this determines the name of the generated .dll).

In your .NET project, add a reference to MatlabGraph.dll (the .NET .dll we have just compiled from Graph2D.m ). This will be 32-bit if its compiled with the 32-bit release of Matlab.

In your .NET project, add a reference to the 32-bit version of MWArray.dll. You can find this by searching the Matlab install directory. Again, make sure that everything is either consistently 32-bit, or consistently 64-bit.

If you choose 32-bit , your .NET app must be compiled for x32, you must use the 32-bit version of Matlab (it will show 32-bit in the splash screen) to export the .NET .dll, and you must import the 32-bit version of MWArray.dll into your .NET project. If you choose 64-bit , compile your .NET app into All CPU, you must use the 64-bit version of Matlab (it will show 64-bit in the splash screen) to export the .NET .dll, and you must import the 64-bit version of MWArray.dll into your .NET project.

Run the .NET app, and it will display the graph above, by calling the Matlab runtimes.

If you want to deploy this to a new PC, you will have to install the .NET runtimes on this PC (these are royalty free). The nice thing about this is that you can customize the graphs in Matlab to your hearts content, using all the power of Matlab. You could do 3-D graphs: create a new figure in Matlab using File..New..Figure, customize it using Insert, then generate the .m code using File..Generate M file. Its fairly obvious what the lines in the newly generated .m file do, you can copy them into your original Graph2D.m file, then regenerate MatlabGraph.dll. For example, adding a title to the figure adds a line title({'My new title}); to the auto-generated .m file. If there is any interest, I can provide the complete C# sample project in .NET.