pyvista-support icon indicating copy to clipboard operation
pyvista-support copied to clipboard

Access discrete area of color map over polydata

Open RP-101 opened this issue 3 years ago • 3 comments

Any advice help with the following would be appreciated.

I am trying to calculate the area of a polydata set - for instance in the example below the total sq.m of area that is colored blue, yellow, red for example. I am aware I could slice the model in the example below to determine the areas - however want to determine a generic method for determining the area of the discrete colormap, as I want to apply this to a more complex model where the color boundaries are arbitrary geometries. Thanks in advance!

https://docs.pyvista.org/examples/02-plot/cmap.html#sphx-glr-examples-02-plot-cmap-py

RP-101 avatar Dec 30 '20 13:12 RP-101

The color displayed is determined by the scalar value which in this sample is mesh['value']. And you accutally know the scalar range of each color. In this case it's assigned in the code:

newcolors[mapping >= 80] = red
newcolors[mapping < 80] = grey
newcolors[mapping < 55] = yellow
newcolors[mapping < 30] = blue
newcolors[mapping < 1] = black

So you can filter the mesh by the scalar range like:

red_points = mesh.points[mesh['values'] >= 80]
mesh_red = pv.PolyData(red_points)

Or if you just want to know the area, that will be the area of each point times the number of the selected points:

n_points_selected = np.count_nonzero(mesh['values'] >= 80)
x_width = mesh.x[1, 0, 0] - mesh.x[0, 0, 0]
y_width = mesh.y[0, 1, 0] - mesh.y[0, 0, 0]
point_area = x_width * y_width
area_selected = point_area * n_points_selected

109021017 avatar Dec 31 '20 03:12 109021017

Thanks for the comment, although I’m trying to make the function a bit more generic suitable for quad elements as well. Also if I’m reality a contour band crossed between two nodes the area for this contour would not be calculated. There is also the threshold method, however this is not going to have the accuracy required.

I understand the contouring that is plotted within VTK is based on the marching squares algorithm (https://lorensen.github.io/VTKExamples/site/VTKBook/06Chapter6/), and it must be plotting the colours as meshes further discretized meshes - I was hoping there would be a feature to access the generated sub mesh that is subsequently contoured over the mesh. Another way may be to simply produce the contour mesh myself to calculate the areas if the area properties are not available from vtk. Any further advice via the vtk route would be helpful?

RP-101 avatar Dec 31 '20 17:12 RP-101

@109021017's comment is 💯

Also if I’m reality a contour band crossed between two nodes the area for this contour would not be calculated

This wouldn't really happen. Colors are interpolated between nodes not across nodes.

There is also the threshold method, however this is not going to have the accuracy required.

It should be?

and it must be plotting the colours as meshes further discretized meshes - I was hoping there would be a feature to access the generated sub mesh that is subsequently contoured over the mesh.

This is not the case. There is no such further discretized mesh. The colors are interpolated across nodes.

See https://docs.pyvista.org/examples/02-plot/interpolate-before-map.html#interpolate-before-mapping for some insight.

Another way may be to simply produce the contour mesh myself to calculate the areas if the area properties are not available from vtk.

That's what I'd recommend using the contour filter and the list of contour values that would be discretizing your colormap.

banesullivan avatar Apr 07 '21 01:04 banesullivan