Logarithmic Axis Labels/Ticks Customization
Asked Answered
P

3

10

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?

Panelboard answered 27/4, 2012 at 8:54 Comment(1)
A related example is shown here.Dithyramb
D
7

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 https://mcmap.net/q/430270/-logarithmic-axis-labels-ticks-customization */
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();
        }
    });
}
Dithyramb answered 27/4, 2012 at 15:17 Comment(1)
See also Initial Threads.Dithyramb
T
5

I think what you need is logAxis.setNumberFormatOverride(NumberFormat format);

EDIT: Since further help is needed... try this:

logAxis.setBase(10);
LogFormat format = new LogFormat(logAxis.getBase(), "", "", true);
logAxis.setNumberFormatOverride(format);

Here's a whole method that can be used to play with...:

  public static void main(String[] args) {
    XYSeries series = new XYSeries("");
    series.add(1, 10);
    series.add(2, 100);
    series.add(3, 1000);
    series.add(4, 10000);
    series.add(5, 100000);
    series.add(6, 1000000);

//    NumberAxis yAxis = new NumberAxis("");
    LogAxis yAxis = new LogAxis("");
    yAxis.setBase(10);
    LogFormat format = new LogFormat(yAxis.getBase(), "", "", true);
    yAxis.setNumberFormatOverride(format);
    XYPlot plot = new XYPlot(
      new XYSeriesCollection(series),
      new NumberAxis(""),
      yAxis,
      new XYLineAndShapeRenderer(true, false));
    JFreeChart chart = new JFreeChart("", 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);
  }
Teenateenage answered 27/4, 2012 at 9:45 Comment(2)
@Biscuitz - then I suspect you didn't try very hard... since I'm feeling generous, I've added some detailed code.Teenateenage
@amaidment, thanks for your further help. I was in a wrong direction before. Thank you so much!Panelboard
S
0

You should use the ChartFactory to create the type of chart you want, and not create the JFreeChart constructor directly. Therefore, this is a better solution than what has been previously posted:

public class MyLogChart 
{
    public static void main(String[] args) 
    {
        XYSeries series = new XYSeries("First");
        series.add(1.0, 1.0);
        series.add(2.0, 10.0);
        series.add(3.0, 100.0);
        series.add(4.0, 1000.0);
        series.add(5.0, 10000.0);
        series.add(6.0, 100000.0);
        series.add(7.0, 1000000.0);
        series.add(8.0, 10000000.0);

        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(series);

        JFreeChart chart = ChartFactory.createXYLineChart(
            "XY Chart",
            "x-axis",
            "y-axis",
            dataset,
            PlotOrientation.VERTICAL,
            false,
            false,
            false
            );
    
        LogarithmicAxis yAxis = new LogarithmicAxis("Y");
    
        XYPlot plot = chart.getXYPlot();
        plot.setRangeAxis(yAxis);
    
        XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer)plot.getRenderer();
        renderer.setSeriesShapesVisible(0, true);
    
        ChartFrame frame = new ChartFrame("My Chart", chart);
        frame.pack();
        frame.setVisible(true);
    }
}
Schoonover answered 6/10, 2014 at 22:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.