|
I'm pretty sure this was due to floating point error where the width and height can be very close to zero after extensive panning and zooming. |
Sorry, something went wrong.
|
That seems likely indeed, but it seems like a quick fix that does not work in general, since it is reasonable for an axis to have very small values when showing scientific data (a nice plot would often benefit from proper units like ns instead of showing 1e-9 values, but in practice the latter is very common). If this is an error caused by ill-conditioning after zooming and panning, I think that it should be possible to find better fixes. I also encountered some issues with extensive zooming (see pygfx/pygfx#1081), so I'm interested in finding a proper solution to that problem. Do you have a testcase for the bug that motivated the introduction of this threshold? |
Sorry, something went wrong.
|
very small values Ah good point, we'll have to think of a better fix a nice plot would often benefit from proper units like ns instead of showing 1e-9 values, but in practice the latter is very common. pint would be a good way to do this, see #729 , setting units on a reference frame (see #772) would probably be a good way to do this. |
Sorry, something went wrong.
|
np.isclose might be a good way to check |
Sorry, something went wrong.
|
When comparing to 0.0, that would amount to abs(x) < atol, and the question becomes what atol should be. numpy's default is close to the machine epsilon for 32-bit floats, which is reasonable in some cases, but not applicable in others. It's hard to say what the comparison should be without knowing what it expected. I don't know what are the edge cases to consider. One example would be a scatter plot with a single point: what is the expected behavior in that case? |
Sorry, something went wrong.
|
Perhaps anything that is 1 bit above float32 0 could work as a threshold? The issue arises when the scene bbox [w, h] = 0, which results in a camera matrix which is unusable. |
Sorry, something went wrong.
|
By "1 bit above 0", if you mean the smallest non-zero positive float32, this is about 1.175494e-38, and I believe that the check "> 0.0" or ">= 1.175494e-38` are equivalent (ignoring denormals and such). I can update the PR to go from != 0.0 to > 0.0 (that should be more robust w.r.t. pathological cases like negative values and NaNs). |
Sorry, something went wrong.
|
Sounds like that should work, hardcoding the binary value should work, 0b0000...1 or something I think, do you want to test it or should I? |
Sorry, something went wrong.
|
BTW looking at your actual use-case repo, I think your SplitXYController should be possible with the existing pygfx controllers? And from this example it looks like you're just trying to create a LineCollection, but in a very roudabout way? https://github.com/cassiersg/scaviz/blob/main/examples/traces_plot.ipynb If you describe what you're trying to do we can help better. |
Sorry, something went wrong.
|
Sounds like that should work, hardcoding the binary value should work, 0b0000...1 or something I think, do you want to test it or should I? I switched to np.finfo(np.float32).smallest_normal (which is approx np.float32(1.1754944e-38)), I think that is it a reasonable value (at that order of magnitude, we keep full precision when computing on GPU). If you describe what you're trying to do we can help better. Thanks for the suggestion. I started a discussion here to not derail this thread. (This PR is not discussed there, I noticed this issue when my code was buggy, I don't have a plot with scales below 0.01 anymore - but I expect to have it in the future.) |
Sorry, something went wrong.
From what I could see, the threshold was arbitrary. It is also not clear that any non-zero value should be a threshold, since all computations should work over the full range of a 32-bit float.