JFreechart Polar Chart shape annotation
Asked Answered
S

1

1

I am trying to color different region of a polar chart with different colors. e.g coloring the region between the angle 20 and 60 and between the radii 2 and 4. How can I do this? I was thinking of using a shape annotation and from there drawing an arc, but it seems there is no shape annotation for polar plots. Any ideas? Thank you

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;

public class test2 extends JFrame {

    private static final String title = "Archimedes' Spiral";

    public test2(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);
        XYSeries ser = new XYSeries("test");
        for (int t = 0; t <= 1 * 360; t++) {
            series.add(90 - t, t);
        }

        for (int t = 0; t <= 1 * 120; t++) {
            ser.add(90 - t, 40);
            ser.add(90 - t, 120);
        }
        result.addSeries(series);
        result.addSeries(ser);
        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π");
        DefaultPolarItemRenderer ren = new DefaultPolarItemRenderer();
        ren.setSeriesFilled(0, true);
        ren.setSeriesFilled(1, true);
        plot.setRenderer(ren);
        JFreeChart chart = new JFreeChart(
            title, JFreeChart.DEFAULT_TITLE_FONT, plot, true);
        chart.setBackgroundPaint(Color.white);
        return chart;
    }

    public static void main(String[] args) {
        test2 demo = new test2(title);
        demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        demo.pack();
        demo.setLocationRelativeTo(null);
        demo.setVisible(true);
    }
}
Shackleford answered 30/6, 2011 at 19:57 Comment(0)
C
1

The DefaultPolarItemRenderer typically used in a PolarPlot has the method setSeriesFilled(), which controls whether a series is filled. The renderer specifies the AlphaComposite.SRC_OVER mode with a value of 50%, so overlapping fills look especially nice.

Addendum: To create the chart seen below, start with this example and reduce the data set's domain from 6π to 2π in createDataset():

for (int t = 0; t <= 1 * 360; t++) { ...

Then make the series filled in createChart():

...
DefaultPolarItemRenderer renderer = new DefaultPolarItemRenderer();
renderer.setSeriesFilled(0, true);
...

enter image description here

Candelaria answered 30/6, 2011 at 21:50 Comment(11)
Thank you. Do you please have an example?Shackleford
Oops, I forgot to change the upper limit in the corner text item.Candelaria
Thanks again. SO, if I getting right, you suggest creating XYseries and defining the shape of the series with the intervals over which I want to apply the colors. If this is so, is there no other way of doing this without creating series?Shackleford
Thank you again. One last thing(hopefully): I am trying to set the series colors. I used setSeriesFilled(0, true) and setSeriesPaint(0, Color.black); But this does not work as nice when more than one series is involved. The first series has transparent color(which is great), but subsequent series have stripes over them. Would you please tell me how to set series with a transparent fill color?Shackleford
Color.black has an alpha of 100%. Let JFreeChart choose the series paint, or specify a suitable value when constructing the desired Color.Candelaria
Sorry, for bring this up again, but my series fill is not as nice as yours. It looks like this: s1122.photobucket.com/albums/l539/jpo2/… Do you have any idea why this will be? ...Just in case this happened to you before.Shackleford
It looks like an inadvertently large multiple of 2π, but I'm guessing.Candelaria
Oh... Same thing happens when I add a filled series to your previous example. Please see above for code. Than youShackleford
Yes, I see a similar appearance. You might also enjoy trying a few rose curves.Candelaria
But, how is the code different from that you have in #6577411? Do you knwo how I can fix it for it to look like what you produce in #6577411?Shackleford
It's the same as this with i = 6.Candelaria

© 2022 - 2024 — McMap. All rights reserved.