Search code examples
javajfreechart

Logarithmic Axis Labels/Ticks Customization


I am using the JFreeChart API to generate some chart in my Java application. In one of my charts, I try to use the LogAxis object to make my y-axis a log-scale axis (A in the figure) by the following code:

LogAxis logAxis = new LogAxis("Price($)");
logAxis.setMinorTickMarksVisible(true);
logAxis.setAutoRange(true);
xyplot.setRangeAxis(logAxis);

enter image description here

Then I got a y-axis in log-scale with ticks like 10^n (like figure A). I want to make it like B, which is more intuitive to the user, and each interval represents different values, as shown in the figure, 2->4, 4->8, 8->16, the interval grows as 2^n. Something minor is that, the intervals are displaying equally wide even if they are representing different value. However, when O try to achieve this by the following code :

LogAxis logAxis = new LogAxis("Price($)");
logAxis.setBase(2);
logAxis.setTickUnit(new NumberTickUnit(2));
logAxis.setMinorTickMarksVisible(true);
logAxis.setAutoRange(true);
xyplot.setRangeAxis(logAxis);

What I get is something like figure C.

How can I achieve figure B?


Solution

  • Even though you're using a LogAxis, you can specify integer tick units, as shown in the variation of @amaidment's example below.

    LogAxis

    /** @see http://stackoverflow.com/a/10353270/230513 */
    private static void createFrame() {
        XYSeries series = new XYSeries("Series");
        for (int i = 0; i <= N; i++) {
            series.add(i, Math.pow(2, i));
        }
        NumberAxis xAxis = new NumberAxis("X");
        xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        LogAxis yAxis = new LogAxis("Y");
        yAxis.setBase(2);
        yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        XYPlot plot = new XYPlot(new XYSeriesCollection(series),
            xAxis, yAxis, new XYLineAndShapeRenderer(true, false));
        JFreeChart chart = new JFreeChart(
            "Chart", JFreeChart.DEFAULT_TITLE_FONT, plot, false);
        JFrame frame = new JFrame("LogAxis Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(new ChartPanel(chart));
        frame.pack();
        frame.setVisible(true);
    }
    
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
    
            @Override
            public void run() {
                createFrame();
            }
        });
    }