JFreeChart缩放BoxLots与几个类别
我目前正在使用JFreeChart基于Java的项目,以显示boxplots。
我的问题是如何显示包含大约20个类别和5 +系列的CategoryDataset的箱型图的图表。
目前如果没有设置ChartPanel的首选大小,Legend,Labels和Annotations是可读的,但BoxLots太小。 或者设置ChartPanel的大小,以使BoxLots具有可接受的大小,但是图例,标签和注释是水平拉伸的。
我的问题是,如何正确缩放箱形图,而不缩放图例的图例,轴标签和注释? 是否可以缩放绘图而不缩放图表的所有元素?
代码示例
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(); } }
设置包含ChartPanel
的首选大小,而不是图表,如下所示。
附录:我不认为你可以有效地添加一个图表滚动窗格。 相反,创build一个类SlidingCategoryDataset
实现BoxAndWhiskerCategoryDataset
。 将滚动条添加到控制第一个显示的索引的框架。
附录:一个不那么雄心勃勃的方法是简单地使用一些适当的控制来分页数据集的一部分,如下面的例子所示。
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); } }); } }