java 具有多个类别的箱线图的 JFreeChart 缩放
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6844759/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JFreeChart scaling of Boxplots with several Categories
提问by dennis
i am currently working on a java-based project using JFreeChart to display boxplots.
我目前正在开发一个基于 Java 的项目,使用 JFreeChart 来显示箱线图。
My Problem is how to display a chart containing boxplots for a CategoryDataset with about 20 Categories and 5+ Series.
我的问题是如何显示包含大约 20 个类别和 5 个以上系列的 CategoryDataset 的箱线图的图表。
Currently if the preferred size of the ChartPanel is not set, the Legend, Labels and Annotations are readable but the Boxplots are too small. Or the size of the ChartPanel is set so that the Boxplots have an acceptable size but then the legend, labels and annotations are horizontally stretched.
目前,如果未设置 ChartPanel 的首选大小,则图例、标签和注释可读,但箱线图太小。或者设置 ChartPanel 的大小,以便 Boxplots 具有可接受的大小,但随后图例、标签和注释被水平拉伸。
My question is, how to correctly scale the boxplots without scaling the legend, axis Labels and annotations of the Chart? Is it possible to scale the Plot without scaling all the elements of the Chart?
我的问题是,如何在不缩放图表的图例、轴标签和注释的情况下正确缩放箱线图?是否可以在不缩放图表的所有元素的情况下缩放绘图?
Code Example
代码示例
import java.awt.Color;
import java.awt.Dimension;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
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.plot.CategoryPlot;
import org.jfree.chart.renderer.category.BoxAndWhiskerRenderer;
import org.jfree.data.statistics.DefaultBoxAndWhiskerCategoryDataset;
public class StretchedBoxAndWhiskerExample{
DefaultBoxAndWhiskerCategoryDataset dataset;
JFreeChart chart;
ChartPanel chartPanel;
JFrame frame;
JScrollPane scrollPane;
public StretchedBoxAndWhiskerExample() {
createCategoryBoxplot();
frame = new JFrame();
scrollPane = new JScrollPane(chartPanel);
scrollPane.setPreferredSize(new Dimension(800,700));
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
frame.add(scrollPane);
frame.pack();
frame.setVisible(true);
}
private void createCategoryBoxplot(){
dataset = createCategoryDataset();
CategoryAxis xAxis = new CategoryAxis("");
NumberAxis yAxis = new NumberAxis("Score");
BoxAndWhiskerRenderer renderer = new BoxAndWhiskerRenderer();
CategoryPlot plot = new CategoryPlot(dataset, xAxis, yAxis, renderer);
createJFreeChart(plot,"Test");
// Design
renderer.setFillBox(false);
renderer.setMeanVisible(false);
chart.setBackgroundPaint(Color.white);
plot.setBackgroundPaint(Color.lightGray);
plot.setDomainGridlinePaint(Color.white);
plot.setDomainGridlinesVisible(true);
plot.setRangeGridlinePaint(Color.white);
plot.getRangeAxis().setRange(-10.5, 10.5);
chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new Dimension(3250,600));
}
private DefaultBoxAndWhiskerCategoryDataset createCategoryDataset() {
dataset = new DefaultBoxAndWhiskerCategoryDataset();
ArrayList<Double> values = createSampleData();
ArrayList<String> categories = createSampleCategories();
for (int i=0;i<=5;i++){
for (String category : categories){
dataset.add(values,i,category);
}
}
return dataset;
}
private ArrayList<String> createSampleCategories() {
ArrayList<String> tmp = new ArrayList<String>();
for (int i=0;i<=20;i++){
tmp.add("Category"+i);
}
return tmp;
}
private ArrayList<Double> createSampleData() {
ArrayList<Double> tmp = new ArrayList<Double>();
for (int i=0;i<10;i++){
tmp.add(5.0);
tmp.add(7.0);
tmp.add(2.0);
tmp.add(4.0);
}
return tmp;
}
private void createJFreeChart(CategoryPlot plot, String title){
chart = new JFreeChart(title, plot);
}
public static void main(String[] args) throws IOException {
StretchedBoxAndWhiskerExample demo = new StretchedBoxAndWhiskerExample();
}
}
采纳答案by trashgod
Set the preferred size of the containing ChartPanel
, not the chart, as shown hereand here.
设置包含的首选大小ChartPanel
,而不是图表,如此处和此处所示。
Addendum: I don't think you can usefully add a chart to a scroll pane. Instead, create a class similar to SlidingCategoryDataset
that implements BoxAndWhiskerCategoryDataset
. Add a scroll bar to the frame that controls the first displayed index.
附录:我认为您不能有效地将图表添加到滚动窗格。相反,创建一个类似于SlidingCategoryDataset
实现的类BoxAndWhiskerCategoryDataset
。向控制第一个显示索引的框架添加滚动条。
Addendum: A somewhat less ambitious approach is simply to page a portion of the data set using some suitable control, as shown in the example below.
附录:一种不那么雄心勃勃的方法是使用一些合适的控件简单地分页数据集的一部分,如下面的示例所示。
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
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.plot.CategoryPlot;
import org.jfree.chart.renderer.category.BoxAndWhiskerRenderer;
import org.jfree.data.statistics.DefaultBoxAndWhiskerCategoryDataset;
/** @see https://stackoverflow.com/questions/6844759 */
public class BoxAndWhiskerDemo {
private static final int COLS = 20;
private static final int VISIBLE = 4;
private static final int ROWS = 5;
private static final int VALUES = 10;
private static final Random rnd = new Random();
private List<String> columns;
private List<List<List<Double>>> data;
private DefaultBoxAndWhiskerCategoryDataset dataset;
private CategoryPlot plot;
private ChartPanel chartPanel;
private JPanel controlPanel;
private int start = 0;
public BoxAndWhiskerDemo() {
createData();
createDataset(start);
createChartPanel();
createControlPanel();
}
private void createData() {
columns = new ArrayList<String>(COLS);
data = new ArrayList<List<List<Double>>>();
for (int i = 0; i < COLS; i++) {
String name = "Category" + String.valueOf(i + 1);
columns.add(name);
List<List<Double>> list = new ArrayList<List<Double>>();
for (int j = 0; j < ROWS; j++) {
list.add(createValues());
}
data.add(list);
}
}
private List<Double> createValues() {
List<Double> list = new ArrayList<Double>();
for (int i = 0; i < VALUES; i++) {
list.add(rnd.nextGaussian());
}
return list;
}
private void createDataset(int start) {
dataset = new DefaultBoxAndWhiskerCategoryDataset();
for (int i = start; i < start + VISIBLE; i++) {
List<List<Double>> list = data.get(i);
int row = 0;
for (List<Double> values : list) {
String category = columns.get(i);
dataset.add(values, "s" + row++, category);
}
}
}
private void createChartPanel() {
CategoryAxis xAxis = new CategoryAxis("Category");
NumberAxis yAxis = new NumberAxis("Value");
BoxAndWhiskerRenderer renderer = new BoxAndWhiskerRenderer();
plot = new CategoryPlot(dataset, xAxis, yAxis, renderer);
JFreeChart chart = new JFreeChart("BoxAndWhiskerDemo", plot);
chartPanel = new ChartPanel(chart);
}
private void createControlPanel() {
controlPanel = new JPanel();
controlPanel.add(new JButton(new AbstractAction("\u22b2Prev") {
@Override
public void actionPerformed(ActionEvent e) {
start -= VISIBLE;
if (start < 0) {
start = 0;
return;
}
createDataset(start);
plot.setDataset(dataset);
}
}));
controlPanel.add(new JButton(new AbstractAction("Next\u22b3") {
@Override
public void actionPerformed(ActionEvent e) {
start += VISIBLE;
if (start > COLS - VISIBLE) {
start = COLS - VISIBLE;
return;
}
createDataset(start);
plot.setDataset(dataset);
}
}));
}
public ChartPanel getChartPanel() {
return chartPanel;
}
public JPanel getControlPanel() {
return controlPanel;
}
public static void main(String[] args) throws IOException {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BoxAndWhiskerDemo demo = new BoxAndWhiskerDemo();
frame.add(demo.getChartPanel(), BorderLayout.CENTER);
frame.add(demo.getControlPanel(), BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}