Search code examples
javajfreechart

JFreechart Boxplot changing size of boxes when coloring the boxes


I am using JFreeChart to make a boxplot (code at the bottom). When I don't add a a coloring per box they are drawn wide and correctly centered (as I want them):

enter image description here

However, when I then color them by x-axis label, they get smaller and are not centered correctly anymore:

enter image description here

How can I get the coloring of the second figure but with the box sizes of the first?


package test;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartUtilities;
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.DefaultBoxAndWhiskerCategoryDataset;

public class test {
    public static void main(String[] args) throws Exception {
    DefaultBoxAndWhiskerCategoryDataset dataset = new DefaultBoxAndWhiskerCategoryDataset();

    // example data
    HashMap<String, ArrayList<Double>> test = new HashMap<String, ArrayList<Double>>();
    test.put("A",new ArrayList<Double>(Arrays.asList(0.8, 1.4, 0.8, 1.9, 1.2)));
    test.put("B",new ArrayList<Double>(Arrays.asList(0.8, 1.4, 0.8, 1.9, 1.2)));
    test.put("C",new ArrayList<Double>(Arrays.asList(0.8, 1.4, 0.8, 1.9, 1.2)));
    test.put("D",new ArrayList<Double>(Arrays.asList(0.8, 1.4, 0.8, 1.9, 1.2)));
    test.put("E",new ArrayList<Double>(Arrays.asList(0.8, 1.4, 0.8, 1.9, 1.2)));
    for (String k : test.keySet()){
        /* change to 
         *     String xAxisLabel = "";
         * to get wide plot
         */
        String xAxisLabel = k;
        dataset.add(test.get(k), xAxisLabel, k);// + beta of interactionterm");
    }
    final CategoryAxis xAxis = new CategoryAxis("Example x-axis");
    final NumberAxis yAxis = new NumberAxis("Example y-axis");
    yAxis.setAutoRangeIncludesZero(false);
    final BoxAndWhiskerRenderer renderer = new BoxAndWhiskerRenderer();
    renderer.setFillBox(true);
    renderer.setSeriesToolTipGenerator(1, new BoxAndWhiskerToolTipGenerator());
    renderer.setMeanVisible(false);
    final CategoryPlot plot = new CategoryPlot(dataset, xAxis, yAxis, renderer);

    final JFreeChart chart = new JFreeChart(
            "Example",
            plot
            );
    final ChartPanel chartPanel = new ChartPanel(chart);
    chartPanel.setPreferredSize(new java.awt.Dimension(3000,1800));
    ChartUtilities.saveChartAsPNG(new File("test.png"), chart, 1000, 600);
    }
}

Solution

  • The difference is that your first picture has one series, but your second picture has five series. Instead of adding lots of series, add one series with five items like your top picture. You can use a custom BoxAndWhiskerRenderer that overrides getItemPaint() to get different colors like they show here for XYLineAndShapeRenderer.

    Edit: To get a matching legend, you need a new DrawingSupplier like this.