Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting different y-axis for two series with JFreeChart

I am using JFreeChart to plot two series of data (XYSeries) using a linechart. The complicating factor is that one of the data series has y-values that are typically much higher than the y-values of my second data series (let's say that the first series has y-values in the order of magnitude of millions, while the second series has y-values in the order of magnitude of hundreds). The existence of the high values in my first data set cause the range of the plot to be such that the y-values of my second data set are not comprehensible anymore.

Adding a second y-axis to the plot, such that both my data series use their own y-axis, would solve this problem. Does anyone know how to do this with JFreeChart?

Current code for completeness:

XYSeriesCollection dataset = new XYSeriesCollection();
XYSeries series1 = new XYSeries("series1");
XYSeries series2 = new XYSeries("series2");

// Here is my code to fill series1 and series2 with data    

dataset.addSeries(series1);
dataset.addSeries(series2);

JFreeChart chart = ChartFactory.createXYLineChart(
    "title", "x-axis title", "y-axis title", dataset, PlotOrientation.VERTICAL, true, true, false
);
chart.getXYPlot().setRenderer(new XYSplineRenderer());
like image 212
Niek Tax Avatar asked Apr 07 '15 14:04

Niek Tax


People also ask

How do I create a JFreeChart without chartfactory?

You can manually create the JFreeChart object instead of using ChartFactory. First generate the datasets and Plot, setting each dataset to an index. Then you can customize the Plot with the necessary Axis and Renderer. Here's an example for doing so with dummy data that has two datasets, each with different magnitude y-values:

How to associate a series with a Y-axis in R?

By default, each index of Y-axis corresponds to the index of series. But, if you want to associate a series with a y-axis, you can target by specifying yaxis.seriesName when building y-axes array. In the above code, 2 series share the same scale (TEAM B), while 1 series plots on another scale (TEAM A)

How to AutoScale the chart for 2 y-axis in apexcharts?

ApexCharts will autoScale the chart for 2 Y-axis as we have provided 2 objects in the array. Note that, the array index matches the same index in the series array. When you provide an array in yaxis instead of object, ApexCharts automatically scales the datasets using auto-generated min/max values.

How to create a chart with multiple y-axis in Excel?

We will start by creating a basic example with 2 Y-axis drawn on the left and right side of the chart area. The main configuration to take care of is the options.yaxis property. For multiple scales chart, the y-axis property will accept array instead of object That’s it.


1 Answers

You can manually create the JFreeChart object instead of using ChartFactory. First generate the datasets and Plot, setting each dataset to an index. Then you can customize the Plot with the necessary Axis and Renderer. Here's an example for doing so with dummy data that has two datasets, each with different magnitude y-values:

    //create the series - add some dummy data
    XYSeries series1 = new XYSeries("series1");
    XYSeries series2 = new XYSeries("series2");
    series1.add(1000, 1000);
    series1.add(1150, 1150);
    series1.add(1250, 1250);

    series2.add(1000, 111250);
    series2.add(1150, 211250);
    series2.add(1250, 311250);

    //create the datasets
    XYSeriesCollection dataset1 = new XYSeriesCollection();
    XYSeriesCollection dataset2 = new XYSeriesCollection();
    dataset1.addSeries(series1);
    dataset2.addSeries(series2);

    //construct the plot
    XYPlot plot = new XYPlot();
    plot.setDataset(0, dataset1);
    plot.setDataset(1, dataset2);

    //customize the plot with renderers and axis
    plot.setRenderer(0, new XYSplineRenderer());//use default fill paint for first series
    XYSplineRenderer splinerenderer = new XYSplineRenderer();
    splinerenderer.setSeriesFillPaint(0, Color.BLUE);
    plot.setRenderer(1, splinerenderer);
    plot.setRangeAxis(0, new NumberAxis("Series 1"));
    plot.setRangeAxis(1, new NumberAxis("Series 2"));
    plot.setDomainAxis(new NumberAxis("X Axis"));

    //Map the data to the appropriate axis
    plot.mapDatasetToRangeAxis(0, 0);
    plot.mapDatasetToRangeAxis(1, 1);   

    //generate the chart
    JFreeChart chart = new JFreeChart("MyPlot", getFont(), plot, true);
    chart.setBackgroundPaint(Color.WHITE);
    JPanel chartPanel = new ChartPanel(chart);
like image 155
copeg Avatar answered Sep 30 '22 18:09

copeg