JFreeChart PolarPlot: mathematical orientation

前端 未结 3 2011
萌比男神i
萌比男神i 2020-11-27 23:00

I\'d like to create a polar plot where the data is plotted in mathematical orientation (thus, the series starts and the east and continues counter-clockwise). The default be

相关标签:
3条回答
  • 2020-11-27 23:06

    The current version of JFreeChart seems to solve this issue a lot easier: There are three methods available:

    setCounterClockwise(true) // changes the direction of the ticks
    setAxisLocation(PolarAxisLocation.EAST_BELOW) // defines the placement of the axis
    setAngleOffset(0);
    

    Complete example adapted from here:

    import java.awt.Color;
    import java.awt.Dimension;
    import javax.swing.JFrame;
    import org.jfree.chart.ChartPanel;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.axis.NumberAxis;
    import org.jfree.chart.axis.ValueAxis;
    import org.jfree.chart.plot.PolarAxisLocation;
    import org.jfree.chart.plot.PolarPlot;
    import org.jfree.chart.renderer.DefaultPolarItemRenderer;
    import org.jfree.data.xy.XYDataset;
    import org.jfree.data.xy.XYSeries;
    import org.jfree.data.xy.XYSeriesCollection;
    
    /**
     * @see http://en.wikipedia.org/wiki/Polar_coordinate_system
     * @see https://stackoverflow.com/questions/3458824
     * @see https://stackoverflow.com/questions/6540390
     * @see https://stackoverflow.com/questions/6576911
     * @see https://stackoverflow.com/a/10227275/230513
     */
    public class ArchimedesSpiral extends JFrame {
    
        private static final String title = "Archimedes' Spiral";
    
        public ArchimedesSpiral(String title) {
            super(title);
            JFreeChart chart = createChart(createDataset());
            ChartPanel panel = new ChartPanel(chart);
            panel.setPreferredSize(new Dimension(500, 500));
            panel.setMouseZoomable(false);
            this.add(panel);
        }
    
        private static XYDataset createDataset() {
            XYSeriesCollection result = new XYSeriesCollection();
            XYSeries series = new XYSeries(title);
            for (int t = 0; t <= 3 * 360; t++) {
                series.add(t, t);
            }
            result.addSeries(series);
            return result;
        }
    
        private static JFreeChart createChart(XYDataset dataset) {
            ValueAxis radiusAxis = new NumberAxis();
            radiusAxis.setTickLabelsVisible(false);
            DefaultPolarItemRenderer renderer = new DefaultPolarItemRenderer();
            renderer.setShapesVisible(false);
            PolarPlot plot = new PolarPlot(dataset, radiusAxis, renderer);
            plot.setCounterClockwise(true);
            plot.setAxisLocation(PolarAxisLocation.EAST_BELOW);
            plot.setAngleOffset(0);
            plot.setBackgroundPaint(new Color(0x00f0f0f0));
            plot.setRadiusGridlinePaint(Color.gray);
            plot.addCornerTextItem("r(θ) = θ; 0 < θ < 6π");
            JFreeChart chart = new JFreeChart(
                title, JFreeChart.DEFAULT_TITLE_FONT, plot, true);
            chart.setBackgroundPaint(Color.white);
            return chart;
        }
    
        public static void main(String[] args) {
            ArchimedesSpiral demo = new ArchimedesSpiral(title);
            demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            demo.pack();
            demo.setLocationRelativeTo(null);
            demo.setVisible(true);
        }
    }
    
    0 讨论(0)
  • 2020-11-27 23:20

    Unfortunately, there seems to be no built-in support for this. The angle labeling can be adapted by overriding the refreshAngleTicks() methods of PolarPlot:

    PolarPlot plot = new PolarPlot() {
    
            @Override
            protected List refreshAngleTicks() {
                List ticks = new ArrayList();
                // produce some ticks, e.g. NumberTick instances
                ticks.add(new NumberTick(0, "90", TextAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, 0));
                ticks.add(new NumberTick(45, "45", TextAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, 0));
                ticks.add(new NumberTick(90, "0", TextAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, 0));
                ticks.add(new NumberTick(135, "315", TextAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, 0));
                ticks.add(new NumberTick(180, "270", TextAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, 0));
                ticks.add(new NumberTick(225, "225", TextAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, 0));
                ticks.add(new NumberTick(270, "180", TextAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, 0));
                ticks.add(new NumberTick(315, "135", TextAnchor.TOP_LEFT, TextAnchor.TOP_LEFT, 0));
                return ticks;
            }
        };
    
    0 讨论(0)
  • 2020-11-27 23:24

    As an aside, org.jfree.chart.plot.PolarPlot appears to have been designed for navigational and geodetic applications.

    Using the transformation θ' = π/4 – θ and overriding refreshAngleTicks(), as suggested by @mort, produces reasonable results.

    Addendum: See also this variation using the new PolarPlot API.

    import java.awt.Color;
    import java.awt.Dimension;
    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.JFrame;
    import org.jfree.chart.ChartPanel;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.axis.NumberAxis;
    import org.jfree.chart.axis.NumberTick;
    import org.jfree.chart.axis.ValueAxis;
    import org.jfree.chart.plot.PolarPlot;
    import org.jfree.chart.renderer.DefaultPolarItemRenderer;
    import org.jfree.chart.renderer.PolarItemRenderer;
    import org.jfree.data.xy.XYDataset;
    import org.jfree.data.xy.XYSeries;
    import org.jfree.data.xy.XYSeriesCollection;
    import org.jfree.ui.TextAnchor;
    
    /**
     * @see http://en.wikipedia.org/wiki/Polar_coordinate_system
     * @see https://stackoverflow.com/questions/3458824
     */
    public class ArchimedesSpiral extends JFrame {
    
        private static final String title = "Archimedes' Spiral";
    
        public ArchimedesSpiral(String title) {
            super(title);
            JFreeChart chart = createChart(createDataset());
            ChartPanel panel = new ChartPanel(chart);
            panel.setPreferredSize(new Dimension(500, 500));
            panel.setMouseZoomable(false);
            this.add(panel);
        }
    
        private static XYDataset createDataset() {
            XYSeriesCollection result = new XYSeriesCollection();
            XYSeries series = new XYSeries(title);
            for (int t = 0; t <= 3 * 360; t++) {
                series.add(90 - t, t);
            }
            result.addSeries(series);
            return result;
        }
    
        private static JFreeChart createChart(XYDataset dataset) {
            ValueAxis radiusAxis = new NumberAxis();
            radiusAxis.setTickLabelsVisible(false);
            PolarItemRenderer renderer = new DefaultPolarItemRenderer();
            PolarPlot plot = new PolarPlot(dataset, radiusAxis, renderer) {
    
                @Override
                protected List refreshAngleTicks() {
                    List<NumberTick> ticks = new ArrayList<NumberTick>();
                    int delta = (int) this.getAngleTickUnit().getSize();
                    for (int t = 0; t < 360; t += delta) {
                        int tp = (360 + 90 - t) % 360;
                        NumberTick tick = new NumberTick(
                            Double.valueOf(t), String.valueOf(tp),
                            TextAnchor.CENTER, TextAnchor.CENTER, 0.0);
                        ticks.add(tick);
                    }
                    return ticks;
                }
            };
            plot.setBackgroundPaint(new Color(0x00f0f0f0));
            plot.setRadiusGridlinePaint(Color.gray);
            plot.addCornerTextItem("r(θ) = θ; 0 < θ < 6π");
            JFreeChart chart = new JFreeChart(
                title, JFreeChart.DEFAULT_TITLE_FONT, plot, true);
            chart.setBackgroundPaint(Color.white);
            return chart;
        }
    
        public static void main(String[] args) {
            ArchimedesSpiral demo = new ArchimedesSpiral(title);
            demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            demo.pack();
            demo.setLocationRelativeTo(null);
            demo.setVisible(true);
        }
    }
    
    0 讨论(0)
提交回复
热议问题