Bug: No scientific notation with negative exponent

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
ruben.demarch
Posts: 3
Joined: Wed Mar 23, 2016 10:43 am
antibot: No, of course not.

Bug: No scientific notation with negative exponent

Post by ruben.demarch » Wed Mar 23, 2016 11:15 am

We are plotting an XY dataset on an XY plot where the Y axis has logarithmic scale, and we configured the plot for the scientific notation, setting "0.#####E0" as pattern for java.text.DecimalFormat of tick units. The result is that it works when the exponent is positive, but when the exponent is negative the standard notation is used. That is, the Y axis I see is

1E3
1E2
1E1
1E0
0.1
0.01
0.001
0.0001

and so on.
Thanks for the support.

david.gilbert
JFreeChart Project Leader
Posts: 11734
Joined: Fri Mar 14, 2003 10:29 am
antibot: No, of course not.
Contact:

Re: Bug: No scientific notation with negative exponent

Post by david.gilbert » Thu Mar 31, 2016 5:44 am

Do you have a sample program that shows this bug? I couldn't reproduce it.
David Gilbert
JFreeChart Project Leader

:idea: Read my blog
:idea: Support JFree via the Github sponsorship program

ruben.demarch
Posts: 3
Joined: Wed Mar 23, 2016 10:43 am
antibot: No, of course not.

Re: Bug: No scientific notation with negative exponent

Post by ruben.demarch » Thu Mar 31, 2016 6:32 pm

Hi David, thanks for the reply. Here is a simple test code:

Code: Select all

import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Random;

import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.LogarithmicAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class NegativeExpPlot {

	public static void main(String[] args) throws IOException {
		int nData = 100;
		Random rg = new Random(100);
		XYSeries ds1 = new XYSeries("rand");
		for (int i = 0; i < nData; i++) {
			ds1.add(rg.nextDouble(), rg.nextDouble()/1000);
		}
		for (int i = 0; i < nData; i++) {
			ds1.add(rg.nextDouble(), rg.nextDouble()*1000);
		}
		
		XYPlot p = new XYPlot(new XYSeriesCollection(ds1), new NumberAxis(), new LogarithmicAxis("log"),new XYLineAndShapeRenderer());
		( (NumberAxis)p.getRangeAxis()).setNumberFormatOverride(new DecimalFormat("0.#####E0"));
		JFreeChart chart = new JFreeChart(p);
		ChartUtilities.saveChartAsJPEG(new File("logaxis.jpg"), chart, 1000, 1000);
	}

}

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

Re: Bug: No scientific notation with negative exponent

Post by John Matthews » Fri Apr 01, 2016 3:24 am

Would LogAxis be an alternative?

Image

Code: Select all

    import java.awt.EventQueue;
    import java.io.IOException;
    import java.text.DecimalFormat;
    import java.util.Random;
    import javax.swing.JFrame;
    import org.jfree.chart.ChartPanel;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.axis.LogAxis;
    import org.jfree.chart.axis.NumberAxis;
    import org.jfree.chart.plot.XYPlot;
    import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
    import org.jfree.data.xy.XYSeries;
    import org.jfree.data.xy.XYSeriesCollection;

    public class NegativeExpPlot {

        public static void main(String[] args) throws IOException {
            EventQueue.invokeLater(new NegativeExpPlot()::display);
        }

        private void display() {
            int nData = 100;
            Random r = new Random(nData);
            XYSeries ds1 = new XYSeries("rand");
            for (int i = 0; i < nData; i++) {
                ds1.add(r.nextDouble(), r.nextDouble() / 1000);
            }
            for (int i = 0; i < nData; i++) {
                ds1.add(r.nextDouble(), r.nextDouble() * 1000);
            }
            LogAxis logAxis = new LogAxis("log");
            XYPlot p = new XYPlot(new XYSeriesCollection(ds1), new NumberAxis(),
                logAxis, new XYLineAndShapeRenderer());
            logAxis.setNumberFormatOverride(new DecimalFormat("0.000E0"));
            JFreeChart chart = new JFreeChart(p);
            JFrame f = new JFrame("Log Axis");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(new ChartPanel(chart));
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }

    }

david.gilbert
JFreeChart Project Leader
Posts: 11734
Joined: Fri Mar 14, 2003 10:29 am
antibot: No, of course not.
Contact:

Re: Bug: No scientific notation with negative exponent

Post by david.gilbert » Fri Apr 01, 2016 5:39 am

Thanks. I see in the LogarithmicAxis class it is coded specifically to format negative exponents differently...I've no idea what the intent behind that was (the class was contributed by another developer a long time ago). I was able to make it work by commenting out some lines in the refreshTicksVertical() method (at around line 940), as follows:

Code: Select all

                            else {    //not "1e#"-type label
//                                if (i >= 0) {   // if positive exponent then
                                                // make integer
                                    NumberFormat format
                                        = getNumberFormatOverride();
                                    if (format != null) {
                                        tickLabel = format.format(tickVal);
                                    }
                                    else {
                                        tickLabel = Long.toString((long)
                                                Math.rint(tickVal));
                                    }
//                                }
//                                else {
                                    //negative exponent; create fractional value
                                    //set exact number of fractional digits to
                                    // be shown:
//                                    this.numberFormatterObj
//                                        .setMaximumFractionDigits(-i);
//                                    //create tick label:
//                                    tickLabel = this.numberFormatterObj.format(
//                                            tickVal);
//                                }
                            }
Alternatively, as John Matthews suggested already, switch to the LogAxis class.
David Gilbert
JFreeChart Project Leader

:idea: Read my blog
:idea: Support JFree via the Github sponsorship program

ruben.demarch
Posts: 3
Joined: Wed Mar 23, 2016 10:43 am
antibot: No, of course not.

Re: Bug: No scientific notation with negative exponent

Post by ruben.demarch » Mon Apr 04, 2016 3:10 pm

Thanks, using LogAxis is an effective workaround.
As a remark, I point out that, differently from LocarithmicAxis, LogAxis does not extend NumberAxis and this can create some more issues.
Anyway, my problems regarding this thing are solved now.
Thank you again for the support.

Locked