Swing2維3維混合動態散點圖

語言: CN / TW / HK

本文已參與【新人創作禮】活動,一起開啟掘金創作之路

Swing2維3維混合動態散點圖

覺得有用的話,歡迎一起討論相互學習~

我的微博我的github我的B站 * 使用的2D繪圖包是jfreechart,3D繪圖包是matplotlib for java V2 * PS:由於和我研究內容相關,如果看到類似SolutionSet的結構體,這是Jmetal中的設定本質我只要其中的double數值。

思路

  1. 一個Jframe
  2. 四個Jpanel,網格佈局
  3. 第一個三維,後三個2維

佈局和繫結

```java MatPlot3DMgr mgr1 = new MatPlot3DMgr();//mgr for obj1 MatPlot3DMgr mgr2 = new MatPlot3DMgr();//mgr for obj2 MatPlot3DMgr mgr3 = new MatPlot3DMgr();//mgr for dcv1 MatPlot3DMgr mgr4 = new MatPlot3DMgr();//mgr for dcv2 JFrame jfx = new JFrame(name1 + name2); JPanel jp1 = new JPanel(); JPanel jp2 = new JPanel(); JPanel jp3 = new JPanel(); JPanel jp4 = new JPanel(); Container contentPaneX; //控制視窗的大小 int jfxwidth = 900; int jfxheight = 900; int subplot_width = 400; int subplot_height = 400; int dcv_dim1 = 3; int dcv_dim2 = 4;

void BindingPanel() {

    contentPaneX = jfx.getContentPane();
    contentPaneX.setLayout(new GridLayout(0, 2));
    jp1.setSize(subplot_width, subplot_height);
    jp2.setSize(subplot_width, subplot_height);
    jp3.setSize(subplot_width, subplot_height);
    jp4.setSize(subplot_width, subplot_height);
    contentPaneX.add(jp1);
    contentPaneX.add(jp2);
    contentPaneX.add(jp3);
    contentPaneX.add(jp4);
    jfx.setDefaultCloseOperation(jfx.EXIT_ON_CLOSE);
    jfx.setSize(jfxwidth, jfxheight);
    jfx.setVisible(true);

}

```

feeding 2Dim data

```java public double[][] pack2Dplotdata(SolutionSet set, int dim1, int dim2) throws JMException { double[][] data = new double[2][set.size()]; for (int i = 0; i < set.size(); i++) { data[0][i] = set.get(i).getDecisionVariables()[dim1].getValue(); data[1][i] = set.get(i).getDecisionVariables()[dim2].getValue(); } return data;

}

```

use Jfreechart to return 2dim Jpanel

```java public ChartPanel plot_2D(double[][] data, String name, String title) { int chartwidth = subplot_width; int chartheight = subplot_height;

    DefaultXYDataset xydataset = new DefaultXYDataset();

    xydataset.addSeries(title, data);//設定點的圖示title一般表示這畫的是決策變數還是目標函式值
    JFreeChart chart = ChartFactory.createScatterPlot(name, "X", "Y", xydataset,
            PlotOrientation.VERTICAL, true, true, false);//設定表頭,x軸,y軸,name表示問題的型別

    //以面板顯示
    ChartPanel chartPanel = new ChartPanel(chart);


    chartPanel.setPreferredSize(new java.awt.Dimension(chartwidth, chartheight));

    return chartPanel;
}

```

plot 2dim scatter

  • 這個好說,可以參考一下JFreechart繪製2D散點圖 ```java public void plot_DCV(SolutionSet set, String name, int dim1, int dim2) throws JMException { double[][] data; if (set.get(0).getSkillFactor() == 0) { data = pack2Dplotdata(set, dim1, dim2); ChartPanel chartPanel = plot_2D(data, name, "dcv"); jp3.removeAll(); jp3.add(chartPanel); jp3.repaint(); jp3.revalidate(); jp3.updateUI(); contentPaneX.repaint(); contentPaneX.revalidate();

    }
    if (set.get(1).getSkillFactor() == 1) {
        data = pack2Dplotdata(set, dim1, dim2);
        ChartPanel chartPanel = plot_2D(data, name, "dcv");
        jp4.removeAll();
        jp4.add(chartPanel);
        jp4.repaint();
        jp4.revalidate();
        jp4.updateUI();
        contentPaneX.repaint();
        contentPaneX.revalidate();
    
    }
    

    } ```

plot 3dim scatter

  • 這個需要使用到matplotlib for java , 具體怎麼使用可以參考使用Matplotlib 3D for JAVA畫三維點陣圖 ```java if (set.get(0).getSkillFactor() == 0) { jp1.removeAll();
            JPanel mgrpanel = mgr.getPanel();
            mgrpanel.setPreferredSize(new Dimension(subplot_width, subplot_height));
            jp1.add(mgrpanel);
        } else {
            jp2.removeAll();
    
            JPanel mgrpanel = mgr.getPanel();
            mgrpanel.setPreferredSize(new Dimension(subplot_width, subplot_height));
            jp2.add(mgrpanel);
        }
    
        mgr.setDataInputType(MatPlot3DMgr.DATA_TYPE_FUNCTION3D);
        mgr.setDataInputType(MatPlot3DMgr.DATA_TYPE_DOTS);
        mgr.getProcessor().setCoordinateSysShowType(mgr.getProcessor().COORDINATE_SYS_ALWAYS_FURTHER);
        mgr.getProcessor().setCoordinateSysTransformationType(mgr.getProcessor().COORDINATE_RANGE_AUTO_FIT);
    
        Point3D[] pointsarray = new Point3D[set.size()];
        ArrayList<Point3D> aa = new ArrayList<>();
        mgr.getProcessor().clear();
        for (int i = 0; i < set.size(); i++) {
            pointsarray[i] = new Point3D(set.get(i).getObjective(0), set.get(i).getObjective(1), set.get(i).getObjective(2));
        }
        for (int i = 0; i < set.size(); i++) {
            aa.add(pointsarray[i]);
        }
        mgr.addData("Objective value", aa);
        mgr.setScaleX(1);
        mgr.setScaleY(1);
        mgr.setScaleZ(1);
        mgr.setSeeta(0.6);
        mgr.setBeita(1.0);
    
        mgr.setTitle(name);
        mgr.fitScreem();
    

    // mgr.show();//這句話是開始一個新的jframe,而不是一個jpanel

        try {
            mgr.updateView(15);
        } catch (Exception e) {
            e.printStackTrace();
        }
    
    }
    

```

  • 有幾點需要注意
  • JPanel mgrpanel = mgr.getPanel(); mgr的本質是輸出一個Jpanel ,如果是直接給到Jframe中會自動適應Frame的大小,但是如果是給到另一個Panel,需要setPreferredSize一下
  • java mgr.setDataInputType(MatPlot3DMgr.DATA_TYPE_FUNCTION3D); mgr.setDataInputType(MatPlot3DMgr.DATA_TYPE_DOTS); mgr.getProcessor().setCoordinateSysShowType(mgr.getProcessor().COORDINATE_SYS_ALWAYS_FURTHER); mgr.getProcessor().setCoordinateSysTransformationType(mgr.getProcessor().COORDINATE_RANGE_AUTO_FIT);
  • mgr包對畫動態散點圖的套話
  • java Point3D[] pointsarray = new Point3D[set.size()]; ArrayList<Point3D> aa = new ArrayList<>(); mgr.getProcessor().clear(); for (int i = 0; i < set.size(); i++) { pointsarray[i] = new Point3D(set.get(i).getObjective(0), set.get(i).getObjective(1), set.get(i).getObjective(2)); } for (int i = 0; i < set.size(); i++) { aa.add(pointsarray[i]); }
  • 其中每個點都是一個Point3D物件,ArrayList aa 的這個集合將這些點組成一個顏色的集合,即在空間中使用一種legend表示,而如果想要表示不同的legend則新建一個集合物件例如bb就好
  • mgr.addData("Objective value", aa); 新增點和legend
  • ```java mgr.setScaleX(1); mgr.setScaleY(1); mgr.setScaleZ(1); mgr.setSeeta(0.6); mgr.setBeita(1.0);
        mgr.setTitle(name);
        mgr.fitScreem();
    

    * 控制座標軸縮放比例和Title 6. 如果在Jframe中表示用show,如果是在JPanel中使用,不要show 7. 動態圖需要重新整理畫布,使用以下語句java try { mgr.updateView(15); } catch (Exception e) { e.printStackTrace(); } ```

效果演示

  • 注意:我的點是動態更新的,也就是說我的資料來源是SolutionSet,這個Set中的OBJ Values 和DCV Values本身都是動態更新的。只是不斷重新整理我的Jpanel而已。