具有多条“散点线”的散点图

发布于 2024-08-14 17:45:23 字数 4870 浏览 12 评论 0原文

好的,我了解 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。它可以很好地工作并绘制散点图,但它不会用不同颜色的点绘制散点图,而是以蓝色绘制“红色散点图”。

干杯,伙计们。

PS我知道我还没有任何通过散点绘制曲线的代码,我将在完成这部分后进行处理=)

Ok, I know about JFreeChart and others, but I'm coding my own simple scatter graph. I've already got a box chart down (without y-axis labels but that shouldn't be a huge problem when I explain it in my report).

I've got a basic scatter graph class, however I've tried to change it so that I can add in different scatter values.

It works, but it only accepts the first scatter array and doesn't draw the rest. Although it does draw the first scatter array in the last scatter array's color... so it's semi-working.

Here's my full ScatterPanel class:

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 is just used to store two long arrays.

Inside my main interface class, I draw a scatter graph like this:

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

A JPanel is set to myScatter. It works and draws the scatter just fine, but it doesn't draw it with different colored points, and it draws the "red scatter" in the color blue.

Cheers guys.

P.S. I know I don't have any code that draws a curved line through the scatter yet, I'll work on that after I finish this part =)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

漆黑的白昼 2024-08-21 17:45:23

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

scatter_values[] will contain a pointer to the arrays scat_size and scat_times. You're changing values in these arrays, so the change will apply to all items in the scatter_values array. Thus it will draw the 3rd graph three times over the top of each other.

You need to add a dimension to the arrays:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文