使用 opencsv 从 csv 文件向 JFreeChart XYDataset 添加值

Adding values to JFreeChart XYDataset from csv file using opencsv

我正在尝试读取 .csv 文件,但我无法理解如何读取 csv 文件中的每一行以及如何将其添加到 XYDataset。

我的算法如下:读入.csv文件->读取每一行->添加到数据集->创建图表->输出为框架

data.csv 有 4 列:TimeXYZ

如何将每个点 (time,x)、(time,y)、(time,z) 添加到数据集中?

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

import com.opencsv.CSVReader;

public class Test extends ApplicationFrame
{
    XYDataset dataset;
    JFreeChart chart;
    final ChartPanel chartPanel;
    final int chartWidth = 560;
    final int chartHeight = 367;
    CSVReader reader;
    String[] readNextLine;
    XYSeries series;

   public Test(String applicationTitle) throws IOException 
   {
      super(applicationTitle); 
      dataset = createDataset(); 
      chart = createChart(dataset);   
      chartPanel = new ChartPanel(chart);  
      chartPanel.setPreferredSize(new java.awt.Dimension(chartHeight, chartWidth));  
   }

   public XYDataset createDataset() throws NumberFormatException, IOException
   {
       dataset = new XYSeriesCollection(); 
       try
       {
           reader = new CSVReader(new FileReader("data.csv")); 
           while((readNextLine = reader.readNext()) != null) 
           {
              if (readNextLine != null)
              {
                  //add values to dataset
              }
           }
     } 
     catch (FileNotFoundException e)
     {
         System.out.println("File not found!");
     }
     return dataset;
   }

 public JFreeChart createChart(XYDataset dataset) throws      NumberFormatException, IOException
 {
    chart = ChartFactory.createXYLineChart(
    "Acceleration vs Time",     //chart title 
    "Time",                     //domain axis label
    "Acceleration",             //range axis label
    createDataset(),            //data
    PlotOrientation.VERTICAL,   //the plot orientation
    true,                       //legend
    true,                       //tooltips
    false);                     //urls

return chart;
}

public static void main(String[] args) throws IOException
{
    final Test demo = new Test("Test XY Line chart");
    demo.pack();
    RefineryUtilities.centerFrameOnScreen(demo);
    demo.setVisible(true);
}
}

我的数据集的前 10 行如下所示:

time    x   y   z
0.003   -0.13   0.83    0.6
0.009   -0.12   0.83    0.61
0.012   -0.12   0.82    0.6
0.018   -0.13   0.81    0.61
0.021   -0.13   0.8 0.61
0.025   -0.12   0.8 0.61
0.033   -0.12   0.79    0.6
0.034   -0.11   0.79    0.6
0.039   -0.11   0.79    0.58
0.044   -0.11   0.77    0.57

您的评论所在 - 您需要首先浏览 readNextLine 的元素,其中 String[] 的每个元素将包含文件中给定行的值(假设您的文件是按照你说的格式正确)。所以 - 你需要把它们变成变量。您尚未指定它们的格式,或 TimeXYZ 的数据类型。

鉴于您正在查看 XY 图表并且您的坐标轴标有 Timeacceleration - 我猜它们都是浮点数, Time 以小数秒为单位,其他变量作为各个轴的加速度。注意 - 如果这个假设是错误的 - 您可能需要使用不同的转换器,例如 Integer.valueOf(),但原理是相同的。

while 循环之前,设置要添加到的系列。您将在 while 循环

中逐行添加它们
final XYSeries seriesX = new XYSeries("X");
final XYSeries seriesY = new XYSeries("Y");
final XYSeries seriesZ = new XYSeries("Z");

while 循环中您的评论

//add values to dataset
double Time = Double.valueOf(readNextLine[0]);
double X = Double.valueOf(readNextLine[1]);
double Y = Double.valueOf(readNextLine[2]);    
double Z = Double.valueOf(readNextLine[3]);
seriesX.add(Time, X);
seriesY.add(Time, Y);
seriesZ.add(Time, Z);

并在 while 循环之后将 3 个系列添加到 return 之前的集合中:

dataset.addSeries(seriesX);
dataset.addSeries(seriesY);
dataset.addSeries(seriesZ);

最后 - 两条评论

  1. 您的数据集创建逻辑有点奇怪。在您的构造函数中,您创建数据集并将其传递给 createChart()。这是很标准的。但是您随后在对 ChartFactory.createXYLineChart( 的调用中内联调用 createDataset(),从而使第一次创建数据变得毫无意义并再次进行。它会工作,但很浪费,并且可能会掩盖您打算让代码执行的其他操作。

  2. if 签入 createDataset() 是多余的 - 您已经处于基于条件的 while 循环中,这意味着它永远为真。

    if (readNextLine != null)
    {
    

编辑 - 添加了完整的工作版本以消除一些评论中的混淆

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

import au.com.bytecode.opencsv.CSVReader;

public class Test extends ApplicationFrame {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    XYSeriesCollection dataset;
    JFreeChart chart;
    final ChartPanel chartPanel;
    final int chartWidth = 560;
    final int chartHeight = 367;
    CSVReader reader;
    String[] readNextLine;
    XYSeries series;

    public Test(String applicationTitle) throws IOException {
        super(applicationTitle);
        dataset = createDataset();
        chart = createChart(dataset);
        chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new java.awt.Dimension(chartHeight,
                chartWidth));
        this.add(chartPanel);
    }

    public XYSeriesCollection createDataset() throws NumberFormatException,
            IOException {
        dataset = new XYSeriesCollection();
        try {
            reader = new CSVReader(new FileReader("res\data.csv"),'\t');
            // Read the header and chuck it away
            readNextLine = reader.readNext();

            // Set up series
            final XYSeries seriesX = new XYSeries("X");
            final XYSeries seriesY = new XYSeries("Y");
            final XYSeries seriesZ = new XYSeries("Z");

            while ((readNextLine = reader.readNext()) != null) {
                // add values to dataset
                double Time = Double.valueOf(readNextLine[0]);
                double X = Double.valueOf(readNextLine[1]);
                double Y = Double.valueOf(readNextLine[2]);
                double Z = Double.valueOf(readNextLine[3]);
                seriesX.add(Time, X);
                seriesY.add(Time, Y);
                seriesZ.add(Time, Z);
            }

            System.out.println(seriesX.getMaxX() + "; " + seriesX.getMaxY());

            dataset.addSeries(seriesX);
            dataset.addSeries(seriesY);
            dataset.addSeries(seriesZ);
        } catch (FileNotFoundException e) {
            System.out.println("File not found!");
        }
        return dataset;
    }

    public JFreeChart createChart(XYDataset dataset)
            throws NumberFormatException, IOException {
        chart = ChartFactory.createXYLineChart("Acceleration vs Time", // chart
                                                                        // title
                "Time", // domain axis label
                "Acceleration", // range axis label
                dataset, // data
                PlotOrientation.VERTICAL, // the plot orientation
                true, // legend
                true, // tooltips
                false); // urls

        return chart;
    }

    public static void main(String[] args) throws IOException {
        System.out.println("In here, to create a Test");
        final Test demo = new Test("Test XY Line chart");
        System.out.println("Created, pakcking");
        demo.pack();
        RefineryUtilities.centerFrameOnScreen(demo);
        demo.setVisible(true);
    }
}

OP 提供前 10 个数据点的输出