Search code examples
javajfreechart

PlotOrientation of BoxAndWhiskerChart JFreeChart


I have a question about JFreeChart: Is it possible to change the PlotOrientation of a BoxAndWhiskerChart to horizontal? I have a histogram, and I want to add a BoxAndWhiskerChart below. I need it horizontal so I can use the same axis scale. I tried to change the orientation in the Plot and ChartPanel.

the look of my JFrame


Solution

  • @Catalina Island shows the correct way to change the PlotOrientation here, but you may run into a bug in the BoxAndWhiskerRenderer shown below for PlotOrientation.HORIZONTAL. Note the truncated line on the lower whisker.

    Original image

    The problem is here in drawHorizontalItem():

    g2.draw(new Line2D.Double(xxMin, yymid - halfW, xxMin, yy + halfW));
    

    which should be this:

    g2.draw(new Line2D.Double(xxMin, yymid - halfW, xxMin, yymid + halfW));
    

    Updated image

    Code as tested:

    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.util.Arrays;
    import javax.swing.JFrame;
    import org.jfree.chart.ChartFactory;
    import org.jfree.chart.ChartPanel;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.plot.CategoryPlot;
    import org.jfree.chart.plot.PlotOrientation;
    import org.jfree.data.statistics.DefaultBoxAndWhiskerCategoryDataset;
    
    /**
     * @see https://stackoverflow.com/a/38407595/230513
     */
    public class BoxPlot {
    
    
        private void display() {
            JFrame f = new JFrame("BoxPlot");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            DefaultBoxAndWhiskerCategoryDataset data = new DefaultBoxAndWhiskerCategoryDataset();
            data.add(Arrays.asList(30, 36, 46, 55, 65, 76, 81, 80, 71, 59, 44, 34), "Planet", "Endor");
            JFreeChart chart = ChartFactory.createBoxAndWhiskerChart(
                "Box and Whisker Chart", "Planet", "Temperature", data, false);
            CategoryPlot plot = (CategoryPlot) chart.getPlot();
            plot.setOrientation(PlotOrientation.HORIZONTAL);
            f.add(new ChartPanel(chart) {
    
                @Override
                public Dimension getPreferredSize() {
                    return new Dimension(500, 300);
                }
            });
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new BoxPlot()::display);
        }
    }