pyvista
pyvista copied to clipboard
When drawing a scatter points spread over multiple areas, the coordinates of gird are incorrect.
Describe the bug, what's wrong, and what you expected.
I have some scatter points spread over multiple areas。When plotting them, the gird line in pyvista does not show correctly.
the plot result of pyvista, the 0 pos of X should in the minddle, but it doesn't。
plot result of matplotlib
Steps to reproduce the bug.
import pyvista as pv
import numpy as np
pl = pv.Plotter()
def generate_snape(center_x):
""" generate scatters """
x = np.linspace(center_x - 1.72364324078285, center_x + 1.72364324078285, 10)
y = np.linspace(-3, 3, 10)
z = np.zeros(len(x) * len(y))
mesh = np.transpose([np.tile(x, len(y)), np.repeat(y, len(x)), z])
_ = pl.add_mesh(mesh)
return mesh
mesh = generate_snape(0)
mesh2 = generate_snape(-10)
mesh3 = generate_snape(10)
_ = pl.show_grid(all_edges=True)
pl.show()
## matplotlib part
#import pandas as pd
#import matplotlib.pyplot as plt
# fig = plt.figure()
# ax = fig.add_subplot()
# ax.scatter(mesh[:,0], mesh[:,1])
# ax.scatter(mesh2[:,0], mesh2[:,1])
# ax.scatter(mesh3[:,0], mesh3[:,1])
# ax.set_xlabel('X Label')
# ax.set_ylabel('Y Label')
# plt.show()
System Information
--------------------------------------------------------------------------------
Date: Tue Jan 23 17:36:07 2024 中国标准时间
OS : Windows
CPU(s) : 12
Machine : AMD64
Architecture : 64bit
RAM : 31.8 GiB
Environment : Python
GPU Vendor : Intel
GPU Renderer : Intel(R) UHD Graphics 630
GPU Version : 4.5.0 - Build 23.20.16.5017
MathText Support : False
Python 3.9.12 (tags/v3.9.12:b28265d, Mar 23 2022, 23:52:46) [MSC v.1929 64
bit (AMD64)]
pyvista : 0.43.0
vtk : 9.2.6
numpy : 1.24.4
matplotlib : 3.5.2
scooby : 0.7.2
pooch : v1.7.0
pillow : 10.0.0
pyvistaqt : 0.11.0
IPython : 8.14.0
ipywidgets : 8.0.7
scipy : 1.9.0
nest_asyncio : 1.5.6
--------------------------------------------------------------------------------
Screenshots
Hi,
Short answer : you can change _ = pl.show_grid(all_edges=True)
by _ = pl.show_grid(all_edges=True, n_xlabels=4)
(or any value strictly smaller than 5, 5 being the default value). It seems that there is a bug here and the ticks are displayed as expected only for small values of n_xlabels
.
Long answer the behavior of show_grid
wrt to n_xlabels
, n_ylabels
and n_ylabels
is surprising. It seems that above a certain threshold, the ticks of the CubeAxesActor are not displayed as expected. In the @Aaron1992's example, the same weird behavior for Y appears as soon as n_ylabels >= 8
.
Changing the scene also changes the values of the threshold, as an example, if we change the way data is generated along the X axis, we can have 5 ticks:
mesh = generate_snape(0)
mesh2 = generate_snape(-5) # -10 in the previous example
mesh3 = generate_snape(5) # 10 in the previous example
_ = pl.show_grid(all_edges=True, n_xlabels=5, n_ylabels=5)
pl.show()
Result:
But here again, with higher values for n_xlabels
and n_ylabels
, we can see the same undesired behavior. The issue appears again as soon as n_xlabels >= 7
.
It seems that the vtk CubeAxesActor wrapped by PyVista has the right list of labels along each axis, but the position of the ticks is not set accordingly. I wasn't able to find a way to reconfigure manually the position of the ticks reading the doc, but my experience with core vtk is limited, perhaps someone can help finding a solution.
I realized that it was possible to guess the maximum value of n_xlabels
with the following trick: In pyvista.plotting.cube_axes_actor
I removed all calls with self._update_x_labels()
, self._update_y_labels() or self._update_z_labels(). Then I ran the example from this issue:
mesh = generate_snape(0)
mesh2 = generate_snape(-10)
mesh3 = generate_snape(10)
grid = pl.show_grid(all_edges=True)
pl.show()
and obtained
My interpretation (I don't fully understand what is going on on the vtk side) is that by default the number of ticks is set to 5, it is possible to reduce it but not increase it afterward, and choosing n_xlabels=5
seems to lead to a translation of the ticks (initially centered) to the boundary of the box, letting on the other side a blank space smaller than intial offset between labels.
In the situation generate_snape(-5)
and generate_snape(5)
, I obtained 7 ticks by default, and again, it was the threshold here:
It seems that there is a maximal number of ticks than can be displayed along each axis, setting at initialization, and then only some reshaping are possible. I tried to fix it playing around with underlying VTK CubeAxesActor but I didn't manage to find a solution. Perhaps someone with more experience with this class will see what's going on here.
unfortunatley, no solution from my side. I just stumbled accros the same bug. Plotting a pointcloud, adding the associated grid with .show_bounds and adjustung the n_xlabels > 7 led to the same issue.
For now we have to keep n_xlabels to default to avoid wrong labeling.
wrong:
correct labeling: