0

3D 等高線プロットの表面等高線を作成するために使用します。3D フィギュアに等高線を描画していますが、これもうまく機能しますが、凡例が表示されないのはなぜですか?

コード:

private void button1_Click(object sender, EventArgs e)
{
    ILArray<float> data = ILSpecialData.sincf(50, 50);

    BackgroundWorker bgw = new BackgroundWorker();
    bgw.DoWork += bgwCreateProcess_DoWork;
    bgw.RunWorkerAsync(data);
}

private void bgwCreateProcess_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    ILArray<float> data = e.Argument as ILArray<float>;

    using (ILScope.Enter())
    {
        ILScene scene = new ILScene();

        ILPlotCube plotCube = new ILPlotCube(twoDMode: false);

        plotCube.Rotation = Matrix4.Rotation(new Vector3(1, 0, 0), Math.PI / 2);

        ILSurface surface = new ILSurface(data);

        List<ContourLevel> conturLevels = new List<ContourLevel>();
        conturLevels.Add(new ContourLevel() { Text = "Limit Max", Value = 0.9f, LineWidth = 2 });
        conturLevels.Add(new ContourLevel() { Text = "Limit Min", Value = -0.1f, LineWidth = 2 });
        conturLevels.Add(new ContourLevel() { Text = "Average", Value = 0.5f, LineWidth = 3 });

        ILContourPlot contourPlot = new ILContourPlot(data, conturLevels, create3D: true);
        plotCube.Children.Add(contourPlot);

        ILLegend legend = new ILLegend();
        legend.Location = new PointF(.99f, 0f);
        surface.Children.Add(legend);

        ILColorbar colorbar = new ILColorbar();
        colorbar.Location = new PointF(.99f, 0.4f);
        surface.Children.Add(colorbar);

        surface.Markable = false;
        surface.Fill.Markable = false;
        surface.Wireframe.Markable = false;

        surface.Wireframe.Visible = true;

        surface.UseLighting = false;

        plotCube.Add(surface);

        scene.Add(plotCube);

        ilPanel.Scene = scene;
    }
}

このコードは、winform、ILPanel、およびボタンに拡張する必要があります。最後に、ボタンの Click イベントをサブスクライブする必要があります。そうしないと状況が変わるため、コードを減らすことはできません。

4

1 に答える 1

1

フェリックス、コードにはいくつかの問題があります。それらのいくつかは、次のバージョンで修正される ILNumerics のバグに関連しています。次のコードは、そのような画像を作成します。

凡例付き等高線図

private void button1_Click(object sender, EventArgs e) {
    ILArray<float> data = ILSpecialData.sincf(50, 50);

    BackgroundWorker bgw = new BackgroundWorker();
    bgw.DoWork += bgwCreateProcess_DoWork;
    bgw.RunWorkerAsync(data);
}

private void bgwCreateProcess_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) {

    using (ILScope.Enter()) {
        ILArray<float> data = e.Argument as ILArray<float>;
        ILScene scene = new ILScene();

        ILPlotCube plotCube = new ILPlotCube(twoDMode: false);

        plotCube.Rotation = Matrix4.Rotation(new Vector3(1, 0, 0), Math.PI / 2);

        ILSurface surface = new ILSurface(data);

        List<ContourLevel> conturLevels = new List<ContourLevel>();
        conturLevels.Add(new ContourLevel() { Text = "Limit Max", Value = 0.9f, LineWidth = 2 });
        conturLevels.Add(new ContourLevel() { Text = "Limit Min", Value = -0.1f, LineWidth = 2 });
        conturLevels.Add(new ContourLevel() { Text = "Average", Value = 0.5f, LineWidth = 3 });

        ILContourPlot contourPlot = new ILContourPlot(data, conturLevels, create3D: true);
        plotCube.Add(contourPlot);

        ILLegend legend = new ILLegend("one","two","three","four");
        legend.Location = new PointF(.99f, 0f);


        ILColorbar colorbar = new ILColorbar();
        colorbar.Location = new PointF(.99f, 0.4f);
        surface.Add(colorbar);

        surface.Markable = false;
        surface.Fill.Markable = false;
        surface.Wireframe.Markable = false;

        surface.Wireframe.Visible = true;

        surface.UseLighting = false;

        plotCube.Add(surface);
        surface.Fill.Visible = false;

        scene.Add(plotCube);

        contourPlot.Add(legend);
        legend.Configure();  // only needed in version 3.2.2.0!
        scene.Configure();

        ilPanel1.Scene = scene;
    }
}

コードをステップ実行しましょう。

  1. ご覧のとおり、表面の塗りつぶしの色を非表示にしました。そうしないと、等高線図のラベルが表面に隠れてしまう可能性があります。

  2. 凡例は、説明しようとしているプロットに追加する必要があります。表面の代わりに等高線図に凡例を追加しました。ただし、何らかの理由で、凡例は等高線図から等高線を自動的に検出しないため...

  3. ...凡例コンストラクターに手動で凡例エントリを追加しました。ここでは、文字列「one」...「three」を使用しました。それを自分の名前に置き換えたいと思うでしょう。

  4. 私が言及したバグのため、legend.Configure() を明示的に呼び出す必要があります。これは、バージョン 3.2.2.0 以降では必要ありません。

  5. バックグラウンド ワーカー スレッドでシーンの変更を行っています。これで問題ありません。ただし、構成が完了したら、パネル自体をリフレッシュするように信号を送る必要があります。ただし、ilPanel.Refresh() は、メイン (GUI) スレッドから呼び出す必要があります。したがって、ilPanel.Refresh() を呼び出すために、bgwCreateProcess_DoWork の最後で Control.Invoke() を使用できるのではないかと思います。そうしないと、変更が表示されません。

于 2013-10-18T15:27:08.870 に答える