K3D-tools / K3D-jupyter

K3D lets you create 3D plots backed by WebGL with high-level API (surfaces, isosurfaces, voxels, mesh, cloud points, vtk objects, volume renderer, colormaps, etc). The primary aim of K3D-jupyter is to be easy for use as stand alone package like matplotlib, but also to allow interoperation with existing libraries as VTK.
MIT License
941 stars 123 forks source link

Extra grid space around high aspect data #431

Closed evanmayer closed 9 months ago

evanmayer commented 1 year ago

Description

When plotting data that covers a high aspect ratio volume in x,y,z, the grid has extra space around the data.

I would like the grid to conform to the volume's bounds specified by the bounds kwarg, or allow manual control, so that the visualization of the data is comprehensible to the viewer.

What I Did

Here is a minimal example that exhibits the problem. data has shape similar to my data. The bounds of the data have an aspect ratio similar to that of the data cube I'm working with (astronomical spectral data cube: right ascension, declination, frequency). By inspection, I believe the data displayed in the plot axes (the "grid") has the span in x,y,z as specified.

data = np.random.random((10, 10, 60))
ret = k3d.volume(
    data,
    bounds=[
        -0.003,0.003,
        -0.003,0.003,
        .7,1.4
    ],
)
plot = k3d.plot()
plot += ret
plot.display()

image

If I try to explicitly change the plot axes limits by doing

[...]
plot = k3d.plot()
plot.grid=[
    -0.003,0.003,
    -0.003,0.003,
    .7,1.4
]
plot += ret
plot.display()

I get the same result, which seems wrong. I expected this to work somewhat like matplotlib or any number of other plotting libraries, where directly specifying axes limits was possible. I understand that there may be some default behavior for the grid size to be different than what is specified for "aesthetic reasons," but not being able to override this is frustrating, and the result is aesthetically worse.

I have tried every combination of plot() args grid_auto_fit, grid=[x0, y0, z0, x1, y1, z1], volume() args bounds, and scaling I can think of, and the above is my best result.

Web console log / python logs

N/A

Thanks for making this library! The volume rendering results and speed are great, I'd just like to know how to have a little more control over it.

GiudiceVitor commented 9 months ago

Any progress on this issue? I've been facing the same problem, where manually setting the bound of the grind doesn't seem to change it

artur-trzesiok commented 9 months ago

I get your point. I believe that grid should always have squares on themself to have consistency in each axis.

Grid in k3d have two types of lines - for minorScale and majorScale (that looks visually good). majorScale/minorScale = 10 (always)

Right now K3D force a grid to have a least size of 2 majorScale in each axis.

for your code:

size of scene = {x: 0.006, y: 0.006, z: 0.7}

So:

majorScale = 0.1 # formula: 10 ** ceil(log10(max(0.006, 0006, 0.7))) / 10
minorScale = 0.01

I can change: Right now K3D force a grid to have a least size of 2 majorScale in each axis. to: Right now K3D force a grid to have a least size of 2 minorScale in each axis.

Results will be like that:

image

Do you feel that this is a better solution? @marcinofulus @GiudiceVitor

GiudiceVitor commented 9 months ago

I feel my point is a bit different: I have a 128x128x128 cube, and I would like to see just that (or have the power to manually change the grid bounds), but it always shows up to 180 in every direction:

image

So far, I've been trying to set the grid bound, by setting grid=[x0, y0, z0, x1, y1, z1] or changing the bound arg, just like @marcinofulus, but to no effect. If I print the grid argument of the plot, it shows (0,128,0,128,0,128), but the display shows differently.

Maybe i'm missing something?

OBS: Btw, great library! Thanks!

GiudiceVitor commented 9 months ago

I understand with your comment that the grid is forced to have at least 2 majorScales on each axis (in my case the major scale is 100). I feel like maybe if I manually change the bound argument, the majorScale should be rescaled to half the bound (for example, 64 in my case), so it is still visually pleasing, but in conformity with my manual bounds. Does it feel like a good solution?

artur-trzesiok commented 9 months ago

Hi @GiudiceVitor,

I know that new solution will not met with all yours needs but I'm feeling that we have good progress (left is previous view, right a new one [on devel branch]):

image image image image

I changed extending grid to nearest minorThick. I also changed way of calculating position of labels on grid

artur-trzesiok commented 9 months ago

So I would like to change a scope of your issue to what is above. Please check a new version that I will release soon. If that will be still a issue for you please add another issue for tweaking it also

artur-trzesiok commented 9 months ago

Hi! Please check https://pypi.org/project/k3d/2.16.1/ :)

GiudiceVitor commented 9 months ago

Works fine by me! Thanks :)

artur-trzesiok commented 9 months ago

Thanks for your feedback!