Reputation: 21
I want to draw a simple boxplot(Box and whisker plot) with some data from the user (1 boxplot not many) and I'm having problem with the DefaultBoxAndWhiskerCategoryDataset Variable in jfreechart. it seems that whatever data I enter just vanishes. the plot is always a triangle instead of a boxplot
package boxplot;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.labels.BoxAndWhiskerToolTipGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.BoxAndWhiskerRenderer;
import org.jfree.data.statistics.BoxAndWhiskerCategoryDataset;
import org.jfree.data.statistics.DefaultBoxAndWhiskerCategoryDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
public class Boxplot extends ApplicationFrame{
@SuppressWarnings("deprecation")
public Boxplot(String title) {
super(title);
final BoxAndWhiskerCategoryDataset dataset = createDataset();
final CategoryAxis xAxis = new CategoryAxis("");
final NumberAxis yAxis = new NumberAxis("Value");
yAxis.setAutoRangeIncludesZero(false);
final BoxAndWhiskerRenderer renderer = new BoxAndWhiskerRenderer();
renderer.setFillBox(false);
renderer.setToolTipGenerator(new BoxAndWhiskerToolTipGenerator());
final CategoryPlot plot = new CategoryPlot(dataset, xAxis, yAxis, renderer);
final JFreeChart chart = new JFreeChart(
"Box-and-Whisker Demo",
plot
);
final ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new java.awt.Dimension(450, 270));
setContentPane(chartPanel);
}
public static void main(String[] args) {
final Boxplot plot = new Boxplot("");
plot.pack();
RefineryUtilities.centerFrameOnScreen(plot);
plot.setVisible(true);
}
private static DefaultBoxAndWhiskerCategoryDataset createDataset() {
System.out.print("Input the data (use space after every input)");
double[] inputData = getInputData();
ArrayList<Double> inputDataList = new ArrayList<Double>();
for (int i=0;i<100;i++)
inputDataList.add(i, inputData[i]);
final DefaultBoxAndWhiskerCategoryDataset dataset
= new DefaultBoxAndWhiskerCategoryDataset();
dataset.add(inputDataList, "1", "2");
return dataset;
}
private static double[] getInputData() {
Scanner scanner = new Scanner(System.in);
double[] data = new double[100];
Arrays.fill(data, -1);
int index =0;
do
{
double temp = scanner.nextDouble();
if (temp==-1)
break;
data[index++]= temp;
}while (scanner.hasNext());
scanner.close();
return data;
}
}
Upvotes: 1
Views: 2076
Reputation: 205855
It's not clear where your example fails. Your recapitulation of the relevant factory method, ChartFactory.createBoxAndWhiskerChart()
shown here, appears correct. It may be easier to start with a simpler working example. Some notes:
For convenience, I've constructed a Scanner
using a String
, rather than System.in
.
I've also simplified getInputData()
to return to a List<Number>
, which is suitable for the dataset's add()
method.
Swing GUI objects should be constructed and manipulated only on the event dispatch thread.
Don't use setPreferredSize()
when you really mean to override getPreferredSize()
. as discussed here.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.statistics.DefaultBoxAndWhiskerCategoryDataset;
/**
* @see https://stackoverflow.com/a/35814571/230513
*/
public class BoxPlot {
private static final String ROW_KEY = "City";
private void display() {
JFrame f = new JFrame("BoxPlot");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DefaultBoxAndWhiskerCategoryDataset data = new DefaultBoxAndWhiskerCategoryDataset();
data.add(getInputData(), ROW_KEY, "Coruscant");
JFreeChart chart = ChartFactory.createBoxAndWhiskerChart(
"Box and Whisker Chart", ROW_KEY, "Temperature", data, false);
f.add(new ChartPanel(chart) {
@Override
public Dimension getPreferredSize() {
return new Dimension(320, 480);
}
});
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private List<Number> getInputData() {
Scanner s = new Scanner("30 36 46 55 65 76 81 80 71 59 44 34");
List<Number> list = new ArrayList<>();
do {
list.add(s.nextDouble());
} while (s.hasNext());
return list;
}
public static void main(String[] args) {
EventQueue.invokeLater(new BoxPlot()::display);
}
}
Upvotes: 2