使用 Matlab 从 C# 控制台应用程序创建图形或绘图? [英] Creating a graph or a plot from a C# console app, using Matlab?

查看:29
本文介绍了使用 Matlab 从 C# 控制台应用程序创建图形或绘图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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();

推荐答案

我最终得到了很好的解决.这是一个示例图,由调用 Matlab .m 文件的 .NET 4.0 C# 控制台应用程序生成:

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:

好处是我们可以使用 Matlab 的所有功能来绘制图形,只需几行 .NET.

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

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

How to do this in .NET:

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

  1. 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").

  1. .NET Main():

  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();
        }
    }
}

  • .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 位版本(Matlab 启动时启动画面中显示 32 位或 64 位).

  • 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).

    1. 以下 Matlab 代码显示了一个图形.将其另存为 Graph2D.m.

    function Graph2D (x,y, titleTop, labelX, labelY)
    
    % Create figure
    myNewFigure = figure;
    
    plot(x,y)
    
    title({titleTop});
    xlabel({labelX});
    ylabel({labelY});
    

  • 通过在控制台输入以下内容在 Matlab 中进行测试(确保将 Matlab 工具栏中的 Current Folder 更改为与 Graph2D.m 相同的目录):

  • 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')
    

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

  • 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).

    在您的 .NET 项目中,添加对 MatlabGraph.dll(我们刚刚从 Graph2D.m 编译的 .NET .dll)的引用.如果使用 Matlab 的 32-bit 版本编译,这将是 32-bit.

    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.

    1. 如果您选择 32-bit ,您的 .NET 应用程序必须针对 x32 编译,您必须使用 32-bit 版本的Matlab(它将在启动画面中显示32-bit)导出.NET .dll,您必须导入MWArray 的32-bit 版本.dll 导入到您的 .NET 项目中.
    2. 如果你选择64-bit,将你的.NET应用编译成All CPU,你必须使用64-bit版本的Matlab(它会在启动画面中显示64-bit)导出.NET .dll,你必须导入MWArray.dll的64-bit版本 到您的 .NET 项目中.
    1. 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.
    2. 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.

  • 运行 .NET 应用程序,它将通过调用 Matlab 运行时显示上面的图表.
  • 如果您想将其部署到新 PC,则必须在这台 PC 上安装 .NET 运行时(这些都是免版税的).
  • 这样做的好处是,您可以使用 Matlab 的所有功能,根据自己的喜好自定义 Matlab 中的图形.您可以制作 3-D 图形:在 Matlab 中使用 File..New..Figure 创建一个新图形,使用 Insert 对其进行自定义,然后使用 Insert 生成 .m 代码代码>文件..生成M文件.新生成的 .m 文件中的行的作用相当明显,您可以将它们复制到原始 Graph2D.m 文件中,然后重新生成 MatlabGraph.dll.例如,为图形添加标题会在自动生成的 .m 文件中添加一行 title({'My new title});.
  • 如果有任何兴趣,我可以提供 .NET 中的完整 C# 示例项目.
  • 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.
  • 这篇关于使用 Matlab 从 C# 控制台应用程序创建图形或绘图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆