带有多个“散点线”的散点图

时间:2009-12-13 00:55:35

标签: java swing scatter-plot scatter

好的,我知道JFreeChart和其他人,但我正在编写自己的简单散点图。我已经有了一个箱形图(没有y轴标签,但是当我在报告中解释它时,这不应该是一个大问题。)

我有一个基本的散点图类,但是我尝试更改它以便我可以添加不同的散点值。

它可以工作,但它只接受第一个散射数组而不会绘制其余数据。虽然它确实在最后一个散射数组的颜色中绘制了第一个散射数组......所以它是半工作的。

这是我的完整ScatterPanel类:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.JPanel;

public class ScatterPanel extends JPanel {
    private TwoArray[] values;
    private String title;
    private String[] color_list;

    // Constructor for ScatterPanel
    public ScatterPanel(TwoArray[] v, String t, String[] c) {
        values = v;
        title = t;
        color_list = c;
    }

    /* This will paint the scatter chart
     * using the values from the above variables:
     * "values", "title" and "color_list"
     */
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;

        // Initialize the titleFont
        Font titleFont = new Font("Verdana", Font.BOLD, 16);
        FontMetrics titleFontMetrics = g.getFontMetrics(titleFont);

        // Get the width of the JPanel
        Dimension d = getSize();
        int clientWidth = d.width;
        //int clientHeight = d.height;

        // Setup the title position and size
        int titleWidth = titleFontMetrics.stringWidth(title);
        int title_y = titleFontMetrics.getAscent();
        int title_x = (clientWidth - titleWidth) / 2;

        // Set the font for the title
        g.setFont(titleFont);

        // Draw the title
        g.drawString(title, title_x, title_y);

        // Initialise min and max display scale
        double min = -0.5;
        double max = 5;

        // Iterate through each different algorithm we are comparing
        for(int point = 0; point < values.length; point++) {
            // Iterate through each algorithm's size array and timing array
            for (int i = 0; i < values[point].array_time.length; i++) {
                // Find the overall max and min for x and y
                double x = (double) values[point].array_size[i];
                double y = (double) values[point].array_time[i];
                // Adjust max and min to include x and y.
                if (x < min)
                    min = x - 0.5;
                if (x > max)
                    max = x + 0.5;
                if (y < min)
                    min = y - 0.5;
                if (y > max)
                    max = y + 0.5;
            }
        }

        g2.translate(getWidth()/2,getHeight()/2);
        g2.scale(getWidth()/(max-min), -getHeight()/(max-min));
        g2.translate(-(max+min)/2, -(max+min)/2);

        // Horizontal size of a pixel in new coords.
        double pixelWidth = (max-min)/getWidth();

        // Vertical size of a pixel in new coord.
        double pixelHeight = (max-min)/getHeight();

        g2.setStroke(new BasicStroke(0));

        // Draw the x and y axis
        g2.setColor(Color.BLUE);
        g2.draw( new Line2D.Double(min,0,max,0));
        g2.draw( new Line2D.Double(0,min,0,max));

        for(int point = 0; point < values.length; point++) {
            if(point % 3 == 0)
                g2.setColor(Color.decode(color_list[0]));
            else if(point % 3 == 1)
                g2.setColor(Color.decode(color_list[4]));
            else if(point % 3 == 2)
                g2.setColor(Color.decode(color_list[8]));

            for (int i = 0; i < values[point].array_time.length; i++) {
                long x = values[point].array_size[i];
                long y = values[point].array_time[i];

                // Plot the x-y co-ords
                g2.draw(new Line2D.Double(x-3*pixelWidth,y,x+3*pixelWidth,y));
                g2.draw(new Line2D.Double(x,y-3*pixelHeight,x,y+3*pixelHeight));
            }
        }
    }
}

TwoArray仅用于存储两个长数组。

在我的主界面类中,我画了一个像这样的散点图:

for(int i = 0; i < scat_size.length; i++)
    scat_size[i] = i;

for(int i = 0; i < scat_times.length; i++)
    scat_times[i] = i;

// This should be 1,1 2,2 3,3 etc. in Red
scatter_values[0] = new TwoArray(scat_size, scat_times);

// Trying to test a large co-ord so this should be green
scat_size[2] = 70;
scat_times[2] = 20;
scatter_values[1] = new TwoArray(scat_size, scat_times);

// Trying to test another different co-ord so this should be blue
scat_size[2] = 3;
scat_times[2] = 7;
scatter_values[2] = new TwoArray(scat_size, scat_times);

myScatter = new ScatterPanel(scatter_values, scat_title, color_list);

JPanel设置为myScatter。它可以正常工作并绘制散射,但它不会用不同颜色的点绘制它,并且它会以蓝色绘制“红色散射”。

干杯。

P.S。我知道我没有任何代码在散布中绘制一条曲线,我将在完成此部分后继续研究=)

1 个答案:

答案 0 :(得分:1)

scatter_values []将包含指向数组scat_size和scat_times的指针。您正在更改这些数组中的值,因此更改将应用​​于scatter_values数组中的所有项。因此,它将在第三个图形的顶部相互绘制三次。

您需要为数组添加维度:

for(int j = 0; j < 3; j++) {
    for(int i = 0; i < scat_size.length; i++)
        scat_size[j][i] = i;

    for(int i = 0; i < scat_times.length; i++)
        scat_times[j][i] = i;
}

// This should be 1,1 2,2 3,3 etc. in Red
scatter_values[0] = new TwoArray(scat_size[0], scat_times[0]);

// Trying to test a large co-ord so this should be green
scat_size[1][2] = 70;
scat_times[1][2] = 20;
scatter_values[1] = new TwoArray(scat_size[1], scat_times[1]);

// Trying to test another different co-ord so this should be blue
scat_size[2][2] = 3;
scat_times[2][2] = 7;
scatter_values[2] = new TwoArray(scat_size[2], scat_times[2]);

myScatter = new ScatterPanel(scatter_values, scat_title, color_list);