XChart icon indicating copy to clipboard operation
XChart copied to clipboard

setxAxisTickLabelsFormattingFunction not working as expected in XYChart

Open creme332 opened this issue 2 years ago • 4 comments

I have the following chart and I want to hide every 2 tick labels on the x-axis.

image

The expected output should be: image

I used the setxAxisTickLabelsFormattingFunction method as follows:

import org.knowm.xchart.QuickChart;
import org.knowm.xchart.SwingWrapper;
import org.knowm.xchart.XYChart;

public class App {
    public static void main(String[] args) throws Exception {
        double[] yData = new double[] { 100, 90, 90, 89, 80, 101, 102, 99 };

        // Create Chart
        XYChart chart = QuickChart.getChart("Sample Chart", "X", "Y", "y(x)", null, yData);

        // hide every 2 xtick labels
        chart.getStyler().setxAxisTickLabelsFormattingFunction(x -> x.intValue() % 2 == 0 ? String.valueOf(x) : " ");

        // Show it
        new SwingWrapper(chart).displayChart();
    }
}

The resulting incorrect chart is:

image

If I change the formatting function to x -> x.intValue() % 2 == 0 ? String.valueOf(x) : "skip", the resulting chart becomes:

image

It seems that there are only 2 unique values of x that are passed to the formatting function instead of 8.

How can I achieve my desired output? Thanks.

Note: I am using xchart-3.8.5.jar.

creme332 avatar Nov 06 '23 07:11 creme332

A random guess without looking into the code. Could it be because this:

x.intValue() % 2

gets rounded down to smaller integer due to Double imprecision? I.e. aren't you effectively performing a comparison with == on Doubles?

mccartney avatar Nov 27 '23 15:11 mccartney

I don't think x.intValue() is the issue. If I simply use x -> String.valueOf(x.intValue()) as my formatting function, the x-axis tick labels seem fine (no rounding off issues): image

creme332 avatar Nov 28 '23 04:11 creme332

The problem seem to be that setxAxisTickLabelsFormattingFunction expects the formatting function to return a unique string for each x.

Formatting function Expected behavior Result
x -> x.intValue() % 2 == 0 ? String.valueOf(x) : " " Hide all odd tick labels Missing tick labels because the function returns the same empty string for odd values of x
x -> String.valueOf(x.intValue()) Show all tick labels Works as expected with no missing labels because each value of x returns a unique string.
x -> x.intValue() % 2 == 0 ? String.valueOf(x.intValue()) : String.valueOf(-x.intValue()) Show negative value of x when x is odd Works as expected with no missing labels because each value of x returns a unique string.

This behavior of setxAxisTickLabelsFormattingFunction does not seem to be documented anywhere.

creme332 avatar Nov 28 '23 05:11 creme332

We have the same problem. Does it make sense to automatically calculate the position and visibility for "Custom-Labels"?

mijoskutt avatar Dec 14 '23 17:12 mijoskutt