knowm / XChart

XChart is a light-weight Java library for plotting data.
http://knowm.org/open-source/xchart
Apache License 2.0
1.48k stars 394 forks source link

setting custom tick labels incompatible with logarithmic axis #834

Open flavius-t opened 3 months ago

flavius-t commented 3 months ago

Hi, I am trying to set a custom tick label formatter for my logarithmic Y-Axis on my XYChart:

chartPanel.getChart().getStyler().setYAxisLogarithmic(true);
chartPanel.getChart().setCustomYAxisTickLabelsFormatter(myFormatFunction)

My original logarithmic axis has tick labels at every power of 10:

{ 1, 10, 1000, 1E4, ..., 1E8, ... }

When I set the custom axis formatter, instead of receiving those values, these are the values my formatter receives:

{ 0.0, 1.0E8, 2.0E8, 3.0E8, 4.0E8, ... }

Also, setting the custom formatter here disables the logarithmic axis display, i.e. the display reverts to non-logarithmic:

image image

Trying to set the axis logarithmic again after adding the formatter as above does not revert to the logarithmic axis appearance.


Is there a way to work around this, or can a fix be added to allow setting custom formatters for logarithmic axes?

timmolter commented 1 month ago

Thank you for the bug report. Could you paste a working example showing the issue in code format so I can reproduce and debug? You can use this as a starting point:

public class TestForIssue834 {

  public static void main(String[] args) throws ParseException {

    XYChart chart = getXYChart();
    new SwingWrapper(chart).displayChart();
  }

  public static XYChart getXYChart() {
    XYChart chart =
        new XYChartBuilder()
            .width(720)
            .height(480)
            .title("getXYSeriesRenderStyle Example")
            .xAxisTitle("Count")
            .yAxisTitle("Value")
            .build();

    double[] xValues = new double[] {1, 2, 3};
    double[] yValues = new double[] {1, 2, 3};
    chart.addSeries("main", xValues, yValues);

    return chart;
  }
}
flavius-t commented 1 month ago

Hi there, here is a quick working example:

import org.knowm.xchart.*;

import java.text.ParseException;

public class TestForIssue834 {
    public static void main(String[] args) throws ParseException {

        XYChart chart = getXYChart();
        new SwingWrapper(chart).displayChart();
    }

    private static String customYAxisTickLabelsFormatter(Double value) {
        System.out.println("Formatting Y Axis Tick Value: " + value);
        if (value < 1e3) {
            return String.format("%.0f nJ", value);
        } else if (value < 1e6) {
            return String.format("%.2f µJ", value / 1e3);
        } else if (value < 1e9) {
            return String.format("%.2f mJ", value / 1e6);
        } else {
            return String.format("%.2f J", value / 1e9);
        }
    }

    public static XYChart getXYChart() {
        XYChart chart =
                new XYChartBuilder()
                        .width(720)
                        .height(480)
                        .title("getXYSeriesRenderStyle Example")
                        .xAxisTitle("Count")
                        .yAxisTitle("Value")
                        .build();

        // todo: uncomment this line to see the error show up in the chart
//        chart.setCustomYAxisTickLabelsFormatter(TestForIssue834::customYAxisTickLabelsFormatter);

        chart.getStyler().setYAxisLogarithmic(true);

        double[] xValues = new double[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
        double[] yValues = new double[] {1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8};
        chart.addSeries("main", xValues, yValues);

        return chart;
    }
}

Thank you.