Escalado JFreeChart de Boxplots con varias categorías

Actualmente estoy trabajando en un proyecto basado en Java usando JFreeChart para mostrar los diagtwigs de caja.

Mi problema es cómo mostrar un gráfico que contiene diagtwigs de caja para un conjunto de datos de categoría con aproximadamente 20 categorías y 5+ series.

Actualmente, si el tamaño preferido de ChartPanel no está configurado, la leyenda, las tags y las anotaciones son legibles, pero los diagtwigs de caja son demasiado pequeños. O bien, el tamaño de ChartPanel está establecido de manera que los diagtwigs de caja tengan un tamaño aceptable, pero luego la leyenda, las tags y las anotaciones se estiran horizontalmente.

Mi pregunta es, ¿cómo escalar correctamente las gráficas de caja sin escalar la leyenda, las tags de los ejes y las anotaciones del gráfico? ¿Es posible escalar el argumento sin escalar todos los elementos del gráfico?

Ejemplo de código

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 values = createSampleData(); ArrayList categories = createSampleCategories(); for (int i=0;i<=5;i++){ for (String category : categories){ dataset.add(values,i,category); } } return dataset; } private ArrayList createSampleCategories() { ArrayList tmp = new ArrayList(); for (int i=0;i<=20;i++){ tmp.add("Category"+i); } return tmp; } private ArrayList createSampleData() { ArrayList tmp = new ArrayList(); 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(); } } 

Establezca el tamaño preferido del ChartPanel contiene, no el gráfico, como se muestra aquí y aquí .

Adición: No creo que pueda agregar un gráfico a un panel de desplazamiento. En su lugar, cree una clase similar a SlidingCategoryDataset que implemente BoxAndWhiskerCategoryDataset . Agregue una barra de desplazamiento al marco que controla el primer índice mostrado.

Adición: Un enfoque algo menos ambicioso es simplemente colocar una parte del conjunto de datos utilizando algún control adecuado, como se muestra en el ejemplo a continuación.

enter image description here

 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 columns; private List>> 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(COLS); data = new ArrayList>>(); for (int i = 0; i < COLS; i++) { String name = "Category" + String.valueOf(i + 1); columns.add(name); List> list = new ArrayList>(); for (int j = 0; j < ROWS; j++) { list.add(createValues()); } data.add(list); } } private List createValues() { List list = new ArrayList(); 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 = data.get(i); int row = 0; for (List 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); } }); } }