Bubble Charts: Controlling the Size of the bubbles

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
TMazzotta
Posts: 40
Joined: Thu Mar 27, 2003 7:11 pm

Bubble Charts: Controlling the Size of the bubbles

Post by TMazzotta » Wed Jun 03, 2015 7:14 pm

Hello -
I am experimenting with using the BubbleChart functionality in JFreechart but I am having difficulty figuring out how to control the size of the bubbles themselves (their diameters).. It seems to be a function of where the bubbles are (their X, Y locations) which doesn't make sense to me.

I would greatly appreciate it if someone could help me get my bubbles all the same size : )!!!!

Here's what I see in 2 charts generated from some simple sample code which creates two bubble charts the exact same way.. The only difference is the x and y locations of the bubbles on each of the 2 charts.

Image

Here is the code that generated the images above..
As you will see when running it, the sizes of the bubbles are very different : (.

Code: Select all

package com.bubbleChartsControllingSizeOfBubbles;

import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JPanel;

import org.jfree.chart.*;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.xy.DefaultXYZDataset;
import org.jfree.data.xy.XYZDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;

public class BubbleTest extends ApplicationFrame
{
	static int chartIndex;
	public BubbleTest( String s,int chartIndex )
	{
		super( s );
		BubbleTest.chartIndex=chartIndex;
		JPanel jpanel = createDemoPanel( );
		jpanel.setPreferredSize(new Dimension( 560 , 370 ) );
		setContentPane( jpanel );
	}

	private static JFreeChart createChart( XYZDataset xyzdataset )
	{
		JFreeChart jfreechart = ChartFactory.createBubbleChart(
				"Why Bubbles Different Sizes?",
				"Weight",
				"AGE",
				xyzdataset,
				PlotOrientation.HORIZONTAL,
				true, true, false);

		XYPlot xyplot = ( XYPlot )jfreechart.getPlot( );
		xyplot.setForegroundAlpha( 0.65F );
		XYItemRenderer xyitemrenderer = xyplot.getRenderer( );
		xyitemrenderer.setSeriesPaint( 0 , Color.blue );
		NumberAxis numberaxis = ( NumberAxis )xyplot.getDomainAxis( );
		numberaxis.setLowerMargin( 0.2 );
		numberaxis.setUpperMargin( 0.5 );
		NumberAxis numberaxis1 = ( NumberAxis )xyplot.getRangeAxis( );
		numberaxis1.setLowerMargin( 0.8 );
		numberaxis1.setUpperMargin( 0.9 );

		return jfreechart;
	}

	public static XYZDataset createDataset( )
	{
		DefaultXYZDataset defaultxyzdataset = new DefaultXYZDataset();

		if (chartIndex==1) {
			for (int team=1; team<=4; team++) {
				double x=0;double y=0;
				if (team==1) {x=16; y=2.6; }
				if (team==2) {x=14; y=2.6; }
				if (team==3) {x=24; y=2.6; }
				if (team==4) {x=23; y=2.3; }
				double ad[ ] = { x };
				double ad1[ ] = { y };
				double ad2[ ] = { 1 }; //bubble diameter??
				double ad3[][] = { ad , ad1 , ad2 };
				defaultxyzdataset.addSeries( "Team "+team , ad3 );
			}

		} else if (chartIndex==2) {
			for (int team=1; team<=4; team++) {
				double x=0;double y=0;
				if (team==1) {x=27.8; y=2.6; }
				if (team==2) {x=30; y=3.0; }
				if (team==3) {x=21.8; y=2.3; }
				if (team==4) {x=4; y=1.6; }
				double ad[ ] = { x };
				double ad1[ ] = { y };
				double ad2[ ] = { 1 }; //bubble diameter??
				double ad3[][] = { ad , ad1 , ad2 };
				defaultxyzdataset.addSeries( "Team "+team , ad3 );
			}
		}

		return defaultxyzdataset;
	}

	public static JPanel createDemoPanel( )
	{
		JFreeChart jfreechart = createChart( createDataset( ) );
		ChartPanel chartpanel = new ChartPanel( jfreechart );

		chartpanel.setDomainZoomable( true );
		chartpanel.setRangeZoomable( true );

		return chartpanel;
	}

	public static void main( String args[ ] )
	{
		BubbleTest bubblechart1 = new BubbleTest( "Bubble 1",1 );
		BubbleTest bubblechart2 = new BubbleTest( "Bubble 2",2 );

		bubblechart1.pack( );
		bubblechart2.pack( );
		RefineryUtilities.positionFrameOnScreen(bubblechart1,0,0);
		RefineryUtilities.positionFrameOnScreen(bubblechart2,0.5,0.50);
		bubblechart1.setVisible( true );
		bubblechart2.setVisible( true );
	}
}


TMazzotta
Posts: 40
Joined: Thu Mar 27, 2003 7:11 pm

Re: Bubble Charts: Controlling the Size of the bubbles

Post by TMazzotta » Fri Jun 05, 2015 1:08 am

I think I figured this one out but would appreciate if someone can confirm my assumptions.

It looks like the size of the bubble is defined by the z value, but it uses this z value as compared to the range of the Y-Axis.

By way of example:
- if the Y-Axis has an upper bound of 10 and a lower bound of 1 and z is set to 1.0, then the bubble will be about 10% of the height of the Y-Axis
- if the Y-Axis has an upper bound of 10 and a lower bound of 1 and z is set to 5.0, then the bubble will be about 50% of the height of the Y-Axis
- If the Y-Axis has an upper bound of 100 and a lower bound of 1 and z is set to 1.0, then the bubble will be about 1% of the height of the Y-Axis
- If the Y-Axis has an upper bound of 100 and a lower bound of 1 and z is set to 5.0, then the bubble will be about 5% of the height of the Y-Axis

Assuming this is correct, it looks like the best way to get the bubbles to be a certain size is to first scan through all the data that will be added to they xyzDataset and figure out the range of the y values (min and max values) then decide what % of the Y-Axis you want your bubbles to be, and multiple that % times (yMax-yMin).

Is this correct? is there a simpler/better way to do this?

any help would be much appreciated..
thanks in advance.

paradoxoff
Posts: 1634
Joined: Sat Feb 17, 2007 1:51 pm

Re: Bubble Charts: Controlling the Size of the bubbles

Post by paradoxoff » Fri Jun 05, 2015 11:51 am

Hi,
your assumptions regarding how an XYBubbleRenderer is calculating the size of a symbol is correct, but not 100 % complete. You can also yuse the x axis to calculate the symbol size, or both. In the latter case, the height of the symbol will be dependent on the range of the y axis, and the width of the symbol will dependent on the range of the x axis. Result: you will most likely get an ellipse as symbok instead of a circle.
If all you want to achieve is a constant symbol size for your data points, I would recommend to not use a bubble chart but a plain scatter chart and then simply adjust the size of the symbols by calling
setSeriesShape(int seriesIndex, Shape theShape) with a suitable shape.

TMazzotta
Posts: 40
Joined: Thu Mar 27, 2003 7:11 pm

Re: Bubble Charts: Controlling the Size of the bubbles

Post by TMazzotta » Wed Jun 10, 2015 8:36 pm

thanks paradoxoff

your suggestions were of great help.

Locked