使用 Matlab 从 C# 控制台应用程序创建图形或绘图? [英] Creating a graph or a plot from a C# console app, using Matlab?
问题描述
如果我在 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:
在 Visual Studio 2010 中为 C# 创建一个新的 .NET 控制台应用程序,并将其更改为 .NET 4.0(右键单击项目,选择属性").
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():
.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).
以下 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.
- 如果您选择
32-bit
,您的 .NET 应用程序必须针对x32
编译,您必须使用32-bit
版本的Matlab(它将在启动画面中显示32-bit
)导出.NET .dll,您必须导入MWArray 的
导入到您的 .NET 项目中.32-bit
版本.dll - 如果你选择
64-bit
,将你的.NET应用编译成All CPU
,你必须使用64-bit
版本的Matlab(它会在启动画面中显示64-bit
)导出.NET .dll,你必须导入MWArray.dll的
到您的 .NET 项目中.64-bit
版本
- If you choose
32-bit
, your .NET app must be compiled forx32
, you must use the32-bit
version of Matlab (it will show32-bit
in the splash screen) to export the .NET .dll, and you must import the32-bit
version ofMWArray.dll
into your .NET project. - If you choose
64-bit
, compile your .NET app intoAll CPU
, you must use the64-bit
version of Matlab (it will show64-bit
in the splash screen) to export the .NET .dll, and you must import the64-bit
version ofMWArray.dll
into your .NET project.
File..New..Figure
创建一个新图形,使用 Insert
对其进行自定义,然后使用 Insert
生成 .m 代码代码>文件..生成M文件代码>.新生成的 .m 文件中的行的作用相当明显,您可以将它们复制到原始 Graph2D.m
文件中,然后重新生成 MatlabGraph.dll
.例如,为图形添加标题会在自动生成的 .m 文件中添加一行 title({'My new title});
.
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.这篇关于使用 Matlab 从 C# 控制台应用程序创建图形或绘图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!