Add data as shapes only in Polar Plot

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
jt_swanson
Posts: 18
Joined: Sat Jun 02, 2012 6:12 pm
antibot: No, of course not.

Add data as shapes only in Polar Plot

Post by jt_swanson » Tue Aug 29, 2017 10:36 pm

I had what I thought was a simple problem. I have 2D data expressed as Z-scores, i.e., a distance of 1.98 is 95% confidence, a distance of 2.58 99% confidence and I wanted to plot the points using a polar plot, so the axis would be radial. In addition, I wanted to color each band by probability.

The latter turned out to be easy, I can generate series with a constant radius and fill the series with an appropriate color.

I am at a total loss how to do the former. I had the naive belief that I could use commands similar to:

Code: Select all

setSeriesShapesVisible( dataSeries, true  );
setSeriesLinesVisible(  dataSeries, false );
like I do for XYLineAndShape plots. But these methods apparently do not exist for the Polar Plot renderer.

I seem to be able to assign a renderer to just one series, I see the method setRenderer() for the PolarPlot. It will only take a PolarItemRenderer. I see the method setShapesVisible() for the PolarItemRenderer. I don't see a method setLinesVisible(). So I still seem to be stuck. I bought the Developer's guide and the examples are often useful, but there is just one really simple example for the polar chart.

Am I just going about this the wrong way and I should try a different plot type? For example, try drawing a bunch of concentric filled circles in an XY plot?

I'm basically trying to make a bull's-eye plot, sadly without much success, so any tips would be appreciated.

John Matthews
Posts: 513
Joined: Wed Sep 12, 2007 3:18 pm

Re: Add data as shapes only in Polar Plot

Post by John Matthews » Tue Aug 29, 2017 11:03 pm

You might be able to use the setSeriesFilled() method of DefaultPolarItemRenderer, which "Sets a flag that controls whether or not a series is filled." There are examples here and here.

jt_swanson
Posts: 18
Joined: Sat Jun 02, 2012 6:12 pm
antibot: No, of course not.

Re: Add data as shapes only in Polar Plot

Post by jt_swanson » Tue Aug 29, 2017 11:50 pm

Maybe I wasn't clear. The part that works is drawing the concentric circles.

The part that does not work is that I then want to plot points, just like you would in a scatter plot, except in polar coordinates. So if I had a green circle, then a yellow band, then a red band, the user could see how many of their points fell in the green, versus the red area.

I thought if I added a new series with just one point, this might work:

Code: Select all

      PolarItemRenderer dataRenderer = new DefaultPolarItemRenderer();
      ((DefaultPolarItemRenderer) dataRenderer).setShapesVisible( true );
      plot.setRenderer( dataSeries, dataRenderer );
where dataSeries is the last series in the XYSeriesCollection and plot comes from:

Code: Select all

      JFreeChart chart = ChartFactory.createPolarChart(
                            "Polar Bulls-Eye", dataset, false, false, false );
      PolarPlot  plot  = (PolarPlot) chart.getPlot();
but the previous command (setShapesVisible) appears to do nothing, no matter what I set dataSeries to.

John Matthews
Posts: 513
Joined: Wed Sep 12, 2007 3:18 pm

Re: Add data as shapes only in Polar Plot

Post by John Matthews » Wed Aug 30, 2017 9:56 am

Maybe override drawSeries(), like this?

jt_swanson
Posts: 18
Joined: Sat Jun 02, 2012 6:12 pm
antibot: No, of course not.

Re: Add data as shapes only in Polar Plot

Post by jt_swanson » Wed Aug 30, 2017 4:21 pm

John,

Thanks, that is an excellent suggestion. I'm working on other stuff today, but I'll post again after I have a chance to try it out.

jt_swanson
Posts: 18
Joined: Sat Jun 02, 2012 6:12 pm
antibot: No, of course not.

Re: Add data as shapes only in Polar Plot

Post by jt_swanson » Sat Sep 02, 2017 11:38 pm

John's suggestion worked great. Since I had series to plot either as points or not, I added a flag as to whether to plot normally or plot just points. I included the sort of thing I did below.

Code: Select all

   class PointPolarItemRenderer extends DefaultPolarItemRenderer
   {
      private ArrayList<Boolean> drawPoints = null;
      public void setDrawPoints( ArrayList<Boolean> drawPoints )
      {
         this.drawPoints = drawPoints;
      }
      @Override
      public void drawSeries(
                     java.awt.Graphics2D       g2,
                     java.awt.geom.Rectangle2D dataArea,
                     PlotRenderingInfo         info,
                     PolarPlot                 plot,
                     XYDataset                 dataset,
                     int                       seriesIndex )
      {
         final int radius = 4;

         System.out.println( "Processing Index " + seriesIndex );
         if ( drawPoints  == null              ||
              seriesIndex >= drawPoints.size() ||
              drawPoints.get( seriesIndex ) == false )
         {
            super.drawSeries( g2, dataArea, info, plot, dataset, seriesIndex );
            return;
         }
         NumberAxis axis      = (NumberAxis) plot.getAxis();
         int        numPoints = dataset.getItemCount( seriesIndex );
         for ( int i = 0; i < numPoints; i++ )
         {
            double    r = dataset.getYValue( seriesIndex, i );
            double    theta = dataset.getXValue( seriesIndex, i );
            Point     point = plot.translateToJava2D(
                                   theta, r, axis, dataArea );
            Ellipse2D shape = new Ellipse2D.Double(
                                  point.x - radius / 2,
                                  point.y - radius / 2,
                                  radius, radius );
            Color     color = (Color) this.lookupSeriesPaint( seriesIndex  );
            g2.setColor( color );
            g2.fill( shape );
            g2.draw( shape );
         }
      }
   }

Locked