I use to create a surface contour of the 3D contour plots. I have now been drawing contour lines in my 3D figure, this also works wonderfully, but the legend is not displayed why?

code:

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

This code should be extended to a winform, a ILPanel and a button. Last but the Click event of the button has to be subscribed. Less code is not possible, because otherwise the situation is changed.

有帮助吗?

解决方案

Felix, there are several issues in the code. Some of them are related to a bug in ILNumerics which will be fixed in the next version. The following code creates an image like that:

Contour Plot with Legend

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

Let's step through the code:

  1. As you see, I hided the surface fill color. Otherwise, the labels of the contour plot might get hidden by the surface.

  2. Legends should be added to the plot they are about to describe. I added the legend to the contourplot instead of the surface. However, for some reasons, the legend does not automatically find the contour lines from the contour plot, so...

  3. ... I added the legend entries manually in the legend constructor. Here, I just used the strings "one"... "three". You will want to replace that with your own names.

  4. Due to the bug I mentioned, you will have to call legend.Configure() explicitely. This will not be needed after version 3.2.2.0.

  5. You are doing the scene modifications in a background worker thread - which is fine! However, after having finished the configuration, the panel must be signaled to refresh itself. ilPanel.Refresh(), however, requires to be called from the main (GUI-) thread. So I suspect, you could use Control.Invoke() at the end of bgwCreateProcess_DoWork in order to call ilPanel.Refresh(). Otherwise, the changes will not display.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top