Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Precision error in gradient #634

Closed
gnefedev opened this issue Nov 18, 2022 · 2 comments
Closed

Precision error in gradient #634

gnefedev opened this issue Nov 18, 2022 · 2 comments

Comments

@gnefedev
Copy link

gnefedev commented Nov 18, 2022

I plot tiles and lets plot interpret one of existed values as NaN

Code:

var plt = letsPlot(
    mapOf(
        "x" to listOf(
            "first",
            "first",
            "second",
            "third",
            "third"
        ),
        "y" to listOf(
            "18",
            "21",
            "21",
            "18",
            "21",
        ),
        "z" to listOf(
            3.5264934876244764E-7,
            0.0974772170888232,
            0.1116666955828674,
            2.58687631451427E-5,
            0.07896070396295593
        )
    )
)
plt += geomTile(
    width = tileFillWidth,
    height = tileFillHeight
) {
    this.x = "x"
    this.y = "y"
    this.fill = "z"
}
plt += scaleFillGradientN(
    colors = listOf(
        "#DFFADC", "#C9F5D3", "#B3F2CF",
        "#9AEBCD", "#80DCCC", "#6DC8D2",
        "#61B7DB", "#5C97DB", "#5A7CD6",
        "#6060C7", "#674BB3", "#693799",
        "#6A277B", "#671D60", "#611347",
    ),
    naValue = Color.BLACK.toHexColor()
)
println(ObjectMapper().writeValueAsString(plt.toSpec()))

writeFile(Paths.get("tmp/reproduce.svg"), plt)
Specification as Json { "mapping": {}, "data": { "x": [ "first", "first", "second", "third", "third" ], "y": [ "18", "21", "21", "18", "21" ], "z": [ 3.5264934876244764E-7, 0.0974772170888232, 0.1116666955828674, 2.58687631451427E-5, 0.07896070396295593 ] }, "kind": "plot", "scales": [ { "aesthetic": "fill", "scale_mapper_kind": "color_gradientn", "na_value": "#000000", "colors": [ "#DFFADC", "#C9F5D3", "#B3F2CF", "#9AEBCD", "#80DCCC", "#6DC8D2", "#61B7DB", "#5C97DB", "#5A7CD6", "#6060C7", "#674BB3", "#693799", "#6A277B", "#671D60", "#611347" ] } ], "layers": [ { "mapping": { "x": "x", "y": "y", "fill": "z" }, "stat": "identity", "width": 0.95, "position": "identity", "geom": "tile", "height": 0.95 } ] }

I expected no black tiles.

I found the source of this behaviour: because of double precision error upper end of the range is not the same as the max value of data. This code divide double by int and multiply it again, in general, it will not be the same as an original.

@gnefedev
Copy link
Author

I found one more case with the same problem.

var plt = letsPlot(
    mapOf(
        "x" to listOf(
            "first",
            "first",
            "second",
            "third",
            "third"
        ),
        "y" to listOf(
            "18",
            "21",
            "21",
            "18",
            "21",
        ),
        "z" to listOf(
            3.5264934876244764E-7,
            0.0974772170888232,
            0.1116666955828674,
            2.58687631451427E-5,
            0.5
        )
    )
)
plt += geomTile(
    width = tileFillWidth,
    height = tileFillHeight
) {
    this.x = "x"
    this.y = "y"
    this.fill = "z"
}
plt += scaleFillGradientN(
    colors = listOf(
        "#DFFADC", "#C9F5D3", "#B3F2CF",
        "#9AEBCD", "#80DCCC", "#6DC8D2",
        "#61B7DB", "#5C97DB", "#5A7CD6",
        "#6060C7", "#674BB3", "#693799",
        "#6A277B", "#671D60", "#611347",
    ),
    trans = "log10",
    naValue = Color.BLACK.toHexColor()
)
println(ObjectMapper().writeValueAsString(plt.toSpec()))

writeFile(Paths.get("tmp/reproduce.svg"), plt)
Specifiaction as Json { "mapping": {}, "data": { "x": [ "first", "first", "second", "third", "third" ], "y": [ "18", "21", "21", "18", "21" ], "z": [ 3.5264934876244764E-7, 0.0974772170888232, 0.1116666955828674, 2.58687631451427E-5, 0.5 ] }, "kind": "plot", "scales": [ { "aesthetic": "fill", "scale_mapper_kind": "color_gradientn", "na_value": "#000000", "colors": [ "#DFFADC", "#C9F5D3", "#B3F2CF", "#9AEBCD", "#80DCCC", "#6DC8D2", "#61B7DB", "#5C97DB", "#5A7CD6", "#6060C7", "#674BB3", "#693799", "#6A277B", "#671D60", "#611347" ], "trans": "log10" } ], "layers": [ { "mapping": { "x": "x", "y": "y", "fill": "z" }, "stat": "identity", "width": 0.95, "position": "identity", "geom": "tile", "height": 0.95 } ] }

Without trans = "log10" it works fine on these numbers, but with trans it plots one of the tiles as NaN.

Additionally, legend is definitely broken in case of log10

reproduce

@alshan alshan added this to the 2022Q4 milestone Nov 18, 2022
@alshan alshan closed this as completed in 346d09b Nov 30, 2022
@alshan
Copy link
Collaborator

alshan commented Nov 30, 2022

After the fix (left - 1st case, right - 2nd case):

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants