Search code examples
javajfreechart

how to change dot shape with jfree polar plot?


I would like to know what are the methods to use to change dots polarplot size and shape . And also if it's possible to disable dots for this type of plot .

here is the code plotting polar of two series with default dots.

Thank you

package jfreechart;

import java.awt.Color;
import javax.swing.JFrame;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PolarPlot;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class JFreeChartPolarChartExample extends JFrame {

   private static final long serialVersionUID = 1L;

   public JFreeChartPolarChartExample(String applicationTitle) {
       super(applicationTitle);
       XYSeriesCollection  dataSet = new XYSeriesCollection();
       
       XYSeries series1 = createRandomData("Series 1", 500);
       XYSeries series2 = createRandomData("Series 2", 60);
  
       dataSet.addSeries(series1);
       dataSet.addSeries(series2);
   
      PolarPlot pp = new PolarPlot();
      pp.setAngleGridlinePaint (Color.BLACK);
       
       JFreeChart polarChart = ChartFactory.createPolarChart(null, dataSet, true, true, false);

       // Adding chart into a chart panel
       ChartPanel chartPanel = new ChartPanel(polarChart);
  
       // settind default size
       chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
     
       setContentPane(chartPanel);
   
   }

   private static XYSeries createRandomData(final String name, final double maxvalue ) {
       final XYSeries series = new XYSeries(name);
       for (double az = 0.0; az < 360.0; az =az+10*Math.random()) 
       {
           final double value = maxvalue*(0.8 +0.2*Math.random());
           series.add(az, value);
       }
       return series;
   }

   public static void main(String[] args) {
       JFreeChartPolarChartExample chart = new JFreeChartPolarChartExample(null);
       chart.pack();
       chart.setVisible(true);
   }
}

Solution

  • with it, default dots are square.

    Yes, the DefaultPolarItemRenderer uses a 6 x 6 square DEFAULT_SHAPE:

    public static final Shape DEFAULT_SHAPE =
       new Rectangle2D.Double(-3.0, -3.0, 6.0, 6.0);
    

    how to [make] them round and smaller?

    As suggested here, use a custom DrawingSupplier. In the example below, the default Shape for all series is set to a circle of radius 2.5. ShapeUtils, shown in a comment, may also be useful:

    DefaultPolarItemRenderer renderer = (DefaultPolarItemRenderer) polarPlot.getRenderer();
    renderer.setAutoPopulateSeriesShape(false);
    renderer.setDefaultShape(new Ellipse2D.Double(-2, -2, 5, 5));
    //renderer.setDefaultShape(ShapeUtils.createDiamond(3));
    

    how to disabled them?

    Invoke setShapesVisible() as warranted:

    renderer.setShapesVisible(true);
    

    In addition,

    • You can zoom the chart radially as shown here.

    • Instead of making a new PolarPlot(), get the one instantiated by the chart's factory.

    • To establish the chart's initial size, override getPreferredSize(), as suggested here.

    • Use (nearly) equal width and height to maximize the plot in the enclosing container.

    • Construct and manipulate Swing GUI objects only on the event dispatch thread.

    image

    As tested:

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.GridLayout;
    import java.awt.geom.Ellipse2D;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import org.jfree.chart.ChartFactory;
    import org.jfree.chart.ChartPanel;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.axis.NumberAxis;
    import org.jfree.chart.axis.NumberTickUnit;
    import org.jfree.chart.plot.PolarPlot;
    import org.jfree.chart.renderer.DefaultPolarItemRenderer;
    import org.jfree.chart.util.ShapeUtils;
    import org.jfree.data.xy.XYDataset;
    import org.jfree.data.xy.XYSeries;
    import org.jfree.data.xy.XYSeriesCollection;
    
    /**
     * @see https://stackoverflow.com/q/71632468/230513
     * @see https://stackoverflow.com/a/46931762/230513
     */
    public class Skyplot {
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Skyplot()::plot);
        }
    
        private void plot() {
            JFrame plotFrame = new JFrame("PolarPlot");
            plotFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            plotFrame.add(new Plotter());
            plotFrame.pack();
            plotFrame.setLocationRelativeTo(null);
            plotFrame.setVisible(true);
        }
    
        private static final class Plotter extends JPanel {
    
            public Plotter() {
                super(new GridLayout());
                this.add(createChartPanel(getXYDataset()));
            }
    
            private ChartPanel createChartPanel(XYDataset dataset) {
                JFreeChart chart = ChartFactory.createPolarChart(
                    "Random Data", dataset, true, true, false);
    
                PolarPlot polarPlot = (PolarPlot) chart.getPlot();
                polarPlot.setAngleGridlinePaint (Color.BLACK);
                polarPlot.setRadiusGridlinePaint(Color.BLACK);
    
                DefaultPolarItemRenderer renderer = (DefaultPolarItemRenderer) polarPlot.getRenderer();
                renderer.setAutoPopulateSeriesShape(false);
                renderer.setDefaultShape(new Ellipse2D.Double(-2, -2, 5, 5));
                //renderer.setDefaultShape(ShapeUtils.createDiamond(3));
                renderer.setShapesVisible(true);
    
                NumberAxis rangeAxis = (NumberAxis) polarPlot.getAxis();
                rangeAxis.setTickUnit(new NumberTickUnit(100.0));
    
                return new ChartPanel(chart) {
                    @Override
                    public Dimension getPreferredSize() {
                        return new Dimension(500, 500);
                    }
                };
            }
    
            private XYDataset getXYDataset() {
                XYSeriesCollection dataset = new XYSeriesCollection();
                dataset.addSeries(createRandomData("Series 1", 500));
                dataset.addSeries(createRandomData("Series 2", 60));
                return dataset;
            }
    
            private static XYSeries createRandomData(final String name, final double maxvalue) {
                final XYSeries series = new XYSeries(name);
                for (double az = 0.0; az < 360.0; az = az + 10 * Math.random()) {
                    final double value = maxvalue * (0.8 + 0.2 * Math.random());
                    series.add(az, value);
                }
                return series;
            }
        }
    }