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

发布于 2024-12-08 08:32:48 字数 114 浏览 0 评论 0 原文

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

my2DArray.PlotInMatlab();

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花间憩 2024-12-15 08:32:48

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

在此处输入图像描述

令人高兴的是,我们可以使用 Matlab 的所有功能来绘制图形,而只需几行 .NET。

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

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

  2. .NET Main():

    使用系统;
    使用系统诊断;
    
    命名空间 MyPlotGraphUsingMatlabRuntimes
    {
        /// <摘要>
        /// 从 .NET 控制台应用程序在 Matlab 中显示图形。
        /// 
        班级计划
        {
            静态无效主(字符串[]参数)
            {
                var x = 新的双[100];
                var y = 新的双[100];
                for (int i = 0; i < 100; i++) {
                    x[i] = i;
                    y[i] = 2 ^ i;
                }
                MyHelper.MyMatlab.MyGraph2D(x,y);
                Console.Write("[任意键退出]");
                Console.ReadKey();
            }
        }
    }
    
  3. .NET 类提供了与 Matlab 进行互操作的扩展方法(将文件命名为 MyMatlab.cs)。

    使用系统;
    使用 System.Collections.Generic;
    使用 MathWorks.MATLAB.NET.Arrays;
    命名空间 MyHelper
    {
        /// <摘要>
        /// 链式类的集合,使 Matlab 访问更容易。
        /// 
        公共静态类 MyMatlab
        {
            /// <摘要>
            /// 返回一个可以传递到 Matlab 的格式的双精度值。
            /// 
            /// Double 转换为我们可以传入 Matlab 的形式。
            /// Matlab 格式的双精度值。
            公共静态MWNumericArray MyToMatlab(此双toMatlab)
            {
                返回新的 MWNumericArray(toMatlab);
            }
            /// <摘要>
            /// 将包含单个 Matlab 返回参数的数组转换回 .NET double。
            /// 
            /// MWArray 变量,从 Matlab 代码返回。
            /// .NET double.;
            公共静态双MyToDouble(此MWArray toDouble)
            {
                var matNumericArray = (MWNumericArray)toDouble;
                返回 matNumericArray.ToScalarDouble();
            }
            /// <摘要>
            /// 将包含多个 Matlab 返回参数的数组转换回 .NET 双精度列表。
            /// 
            /// MWArray 变量,从 Matlab 代码返回。
            /// .NET 双精度列表。
            公共静态列表 MyToDoubleList(此 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 数组是从 1 开始的,因此索引为奇数。
                {
                    结果.Add(netArray[i].ToScalarDouble());
                }
                返回结果;
            }
            /// <摘要>
            /// 将包含多个 Matlab 返回参数的数组转换回 .NET 整数列表。
            /// 
            /// MWArray 变量,从 Matlab 代码返回。
            /// .NET 整数列表。
            公共静态列表; MyToMWNumericArray(此 MWArray toList)
            {
                var matNumericArray = toList;
                var netArray = (MWNumericArray)matNumericArray.ToArray();
    
                var 结果 = new List();
                // Console.Write("{0}", netArray[1]);
                for (int i = 1; i <= netArray.NumberOfElements; i++) // Matlab 数组是从 1 开始的,因此索引为奇数。
                {
                    结果.Add(netArray[i].ToScalarInteger());
                }
                返回结果;
            }
            /// <摘要>
            /// 将 int[] 数组转换为 Matlab 参数。
            /// 
            /// MWArray 变量,从 Matlab 代码返回。
            /// .NET 整数列表。
            公共静态 MWNumericArray MyToMWNumericArray(this int[] intArray)
            {
                返回新的 MWNumericArray(1, intArray.Length, intArray); // 行、列 int[] realData
            }
            /// <摘要>
            /// 将 double[] 数组转换为 Matlab 调用的参数。
            /// 
            ///  双精度数组。
            /// MWNumericArray 适合传递到 Matlab 调用。
            公共静态 MWNumericArray MyToMWNumericArray(this double[] arrayOfDoubles)
            {
                返回新的 MWNumericArray(1, arrayOfDoubles.Length, arrayOfDoubles); // 行、列 int[] realData
            }
            /// <摘要>
            /// 将双精度列表转换为 Matlab 调用的参数。
            /// 
            /// 双打列表。
            /// MWNumericArray 适合传递到 Matlab 调用。
            公共静态 MWNumericArray MyToMWNumericArray(此列表 listOfDoubles)
            {
                返回新 MWNumericArray(1, listOfDoubles.Count, listOfDoubles.ToArray()); // 行、列 int[] realData
            }
            /// <摘要>
            /// 将某种类型的列表转换为相同类型的数组。
            /// 
            /// 某种类型的列表。
            /// 某种类型的数组。
            公共静态 T[] MyToArray(此列表 toArray)
            {
                var copy = new T[toArray.Count];
                for (int i = 0; i < toArray.Count; i++) {
                    复制[i] = toArray[i];
                }
                返回副本;
            }
            静态私有只读 MatlabGraph.Graph MatlabInstance = new MatlabGraph.Graph();
            /// <摘要>
            /// 绘制二维图。
            /// 
            /// 双精度数组,x 轴。
            /// 双精度数组,y 轴。
            /// 绘图标题。
            /// X 轴标签。
            /// Y 轴标签。
            static public void MyGraph2D(List x, List y, 字符串标题 = "标题", 字符串 xaxis = "xaxis", 字符串 yaxis = "yaxis")
            {
                MatlabInstance.Graph2D(x.MyToMWNumericArray(), y.MyToMWNumericArray(), 标题, xaxis, yaxis);
            }
            /// <摘要>
            /// 绘制二维图。
            /// 
            /// 双精度数组,x 轴。
            /// 双精度数组,y 轴。
            /// 绘图标题。
            /// X 轴标签。
            /// Y 轴标签。
            静态公共无效MyGraph2D(双[] x,双[] y,字符串标题=“标题”,字符串xaxis =“xaxis”,字符串yaxis =“yaxis”)
            {
                MatlabInstance.Graph2D(x.MyToMWNumericArray(), y.MyToMWNumericArray(), 标题, xaxis, yaxis);
            }
            /// <摘要>
            /// 此类的单元测试。使用 Matlab 显示图形。
            /// 
            静态公共无效单元()
            {
                {
                    var x = 新的双[100];
                    var y = 新的双[100];
                    for (int i = 0; i < 100; i++) {
                        x[i] = i;
                        y[i] = Math.Sin(i);
                    }
                    MyGraph2D(x, y);                
                }
    
                {
                    var x = 新的双[100];
                    var y = 新的双[100];
                    for (int i = 0; i < 100; i++) {
                        x[i] = i;
                        y[i] = 2 ^ i;
                    }
                    MyGraph2D(x, y);
                }
            }
        }
    }
    
  4. 接下来,我们将 .m 文件导出到 .NET 程序集中。我使用 Matlab 2010a(这也适用于 2010b)。使用Matlab,32位版本(Matlab启动时在启动屏幕中显示32位或64位)。

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

    函数 Graph2D (x,y, titleTop, labelX, labelY)
    
    % 创建图形
    myNewFigure = 图;
    
    绘图(x,y)
    
    标题({标题顶部});
    xlabel({labelX});
    ylabel({labelY});
    
  6. 通过在控制台中输入以下内容在 Matlab 中进行测试(确保将 Matlab 工具栏中的当前文件夹更改为与Graph2D.m相同的目录) ):

    <前><代码>x = 0:.2:20;
    y = sin(x)./sqrt(x+1);
    Graph2D(x,y,'我的标题','我的x轴','我的y轴')

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

  8. 在您的 .NET 项目中,添加对 MatlabGraph.dll 的引用(我们刚刚从 Graph2D.m 编译的 .NET .dll)。如果使用 32 位 版本的 Matlab 进行编译,则该值为 32 位

  9. 在您的 .NET 项目中,添加对 32 位版本的 MWArray.dll 的引用。您可以通过搜索 Matlab 安装目录找到它。
  10. 再次确保所有内容要么一致32位,要么一致64位
  11. 如果您选择 32 位,您的 .NET 应用必须针对 x32 进行编译,您必须使用 32 位 版本Matlab(它将在启动屏幕中显示32位)导出.NET .dll,并且您必须导入MWArray的32位版本。 dll 到您的 .NET项目。
  12. 如果您选择64位,将.NET应用程序编译为All CPU,则必须使用64位版本的Matlab (它将在启动屏幕中显示64位)导出.NET .dll,并且您必须导入MWArray.dll的64位版本 到您的 .NET 项目中。
  13. 运行 .NET 应用程序,它将通过调用 Matlab 运行时来显示上面的图表。
  14. 如果您想将其部署到新 PC,则必须在此 PC 上安装 .NET 运行时(这些是免版税的)。
  15. 这样做的好处是,您可以利用 Matlab 的所有功能,根据自己的喜好定制 Matlab 中的图形。您可以制作 3D 图形:使用 File..New..Figure 在 Matlab 中创建一个新图形,使用 Insert 对其进行自定义,然后使用 <代码>文件..生成M文件。新生成的 .m 文件中的行的作用相当明显,您可以将它们复制到原始 Graph2D.m 文件中,然后重新生成 MatlabGraph.dll。例如,向图窗添加标题会向自动生成的 .m 文件添加一行 title({'My new title});
  16. 如果有兴趣,我可以提供 .NET 中的完整 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:

enter image description here

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:

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

      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 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);
                  }
              }
          }
      }
      
  2. 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. 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});
      
    2. 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')
      
    3. 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).

    4. 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.

    5. 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.
    6. Again, make sure that everything is either consistently 32-bit, or consistently 64-bit.
      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.
    7. Run the .NET app, and it will display the graph above, by calling the Matlab runtimes.
  3. 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).
  4. 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.
  5. If there is any interest, I can provide the complete C# sample project in .NET.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文