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

Plotting fails only for specific range #931

Closed
Ceronsand opened this issue Apr 29, 2021 · 8 comments
Closed

Plotting fails only for specific range #931

Ceronsand opened this issue Apr 29, 2021 · 8 comments
Labels

Comments

@Ceronsand
Copy link

Ceronsand commented Apr 29, 2021

Steps to reproduce:

]activate --temp
add GLMakie
using GLMakie
plot([1.4030269373737038e6, 1.4030269377481483e6, 1.4030269381214702e6])

ERROR: ArgumentError: range step cannot be zero

Unfortunately i could not yet narrow it down to a reproducible range, error dissapears if something greater than the 6th decimal is changed . Changing the values slightly allows plotting, but the axis doesn't seem aligned properly anymore.
For example:

plot([1.4030269373737038e6, 1.4030269377481483e6, 1.4030279381214702e6])

System Configuration:
Win10, Julia 1.6.1, GLMakie@0.2.8

@Ceronsand Ceronsand changed the title Plotting fails for plot([1.4030269373737038e6, 1.4030269377481483e6, 1.4030269381214702e6]) Plotting fails only for specific range Apr 29, 2021
@jkrumbiegel
Copy link
Member

The problem is that Makie uses Float32 a lot internally, as this is what GPUs want. And your values are very close together, which means some algorithm that tries to find steps between your limits finds zero-width range steps. I have just tried this out, out of interest:

julia> nfloats(a, b) = begin
           n = 0
           while true
               a = nextfloat(a)
               n += 1
               a == b && break
           end
           n
       end

julia> a = Float32(1.4030269373737038e6)
1.4030269f6

julia> b = Float32(1.4030269381214702e6)
1.403027f6

julia> nfloats(a, b)
1

So there is just one step from your low to your high value in Float32. There's currently no better solution than to scale your values up in Float64 before plotting.

@humphreylee
Copy link

Encountered this issue. The workaround works. Suggest better approach to handle this. Thanks.

@musoke
Copy link
Contributor

musoke commented Jun 6, 2022

I have also run into this error with GLMakie v0.6.3.

using Pkg
Pkg.status("GLMakie")

using GLMakie
using Statistics

b = 0:1e-7:2e-6

lines(b)  # works

lines(b .+ 50)  #error

A better solution would be good; it's not as if plotting values with a large mean and small variance is an obscure task.

@asinghvi17
Copy link
Member

Aside from the type requirements (e.g. Rect2f, Point2f, Vec2f), is there anything in Makie or MakieCore (not the backends) which relies on values being Float32?

If not, I could take a look at making Makie independent of float type, possibly accepting anything which is <: AbstractFloat or Real, then converting them in e.g. gl_convert for GLMakie, and leaving them unconverted for CairoMakie.

@ffreyer
Copy link
Collaborator

ffreyer commented Jun 7, 2022

I don't think there is a need for Float32 types in Makie and MakieCore, but changing those to Float64 doesn't solve the problem. Even if the plot type keeps everything as Float64 you eventually need to convert to Float32 in the GL backends and lose precision.

I think what we need to solve this is another step in our conversion pipeline that normalizes data before converting to Float32. Each scene would need an object that keeps track of the total data limits and defines a linear transformation that goes from (min, max) to (-1, +1) (or whatever else makes sense for Float32). That transformation would then apply to each plot in the scene before converting to Float32 to avoid losing too much precision. Axis etc would have to be aware of this and adjust their limits accordingly.

I played around with the idea a bit before and got a very hacky version working but I don't know how to cleanly implement it in the plotting/conversion pipeline.

@musoke
Copy link
Contributor

musoke commented Jun 7, 2022

@ffreyer, I know nearly nothing about the internals of makie, but that sounds like a sensible solution.

@asinghvi17 asinghvi17 reopened this Jun 7, 2022
@islent
Copy link

islent commented Sep 2, 2022

Truncating the array to Float16 saves the world:

julia> a = [31.999999051331837, 31.99999905020038, 31.99999904907261, 31.999999047948524, 31.99999904682809, 31.99999904571132, 31.999999044598198, 31.999999043488696, 31.999999042382818, 31.999999041280553, 31.99999904018189]
11-element Vector{Float64}:
 31.999999051331837
 31.99999905020038
 31.99999904907261
 31.999999047948524
 31.99999904682809
 31.99999904571132
 31.999999044598198
 31.999999043488696
 31.999999042382818
 31.999999041280553
 31.99999904018189

julia> Makie.lines(a)
Error showing value of type Makie.FigureAxisPlot:
ERROR: ArgumentError: range step cannot be zero
...

julia> Makie.lines(Float32.(a))
Error showing value of type Makie.FigureAxisPlot:
ERROR: ArgumentError: range step cannot be zero
...

julia> Makie.lines(Float16.(a))
#! It works!

Related issues:

@musoke
Copy link
Contributor

musoke commented May 9, 2024

Both @Ceronsand's MWE and my MWE are fixed with GLMakie v0.10.0.

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

No branches or pull requests

9 participants