-
Notifications
You must be signed in to change notification settings - Fork 4
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
Scalar ranges for colors on a 3-D object. #35
Comments
Hi @gunjan71011! For this situation, you would need to make your own colormap using Matplotlib and pass that colormap as the Perhaps try an example like this: https://matplotlib.org/gallery/images_contours_and_fields/custom_cmap.html And then pass it to PyVista similar to this example: https://docs.pyvista.org/examples/02-plot/cmap.html FYI: there is a Sent with GitHawk |
Thanks for the clim argument tip! So I payed around with customizing and making my own cmap and putting it into pyvista, however, I still can't get the colors to exactly be between a range of values, more specifically I want it to be between certain ranges of the scalar values used to scale my figure. I can create a colorbar with the exact values I want using matplotlib just fine, but i think you can only use color maps on pyvista using the cmap argument. Would you have any more feedback? Thank you! |
Could you provide your code to make the matplotlib colormap? |
from matplotlib.colors import ListedColormap
from matplotlib import cm
import numpy as np
viridis = cm.get_cmap('viridis', 256)
newcolors = viridis(np.linspace(0, 1, 256))
blue = np.array([12/256, 238/256, 246/256, 1])
black = np.array([11/256, 11/256, 11/256, 1])
grey = np.array([189/256, 189/256, 189/256, 1])
yellow = np.array([255/256, 247/256, 0/256, 1])
red = np.array([1,0,0,1])
newcolors[0] = black #If my scaler is 0 i want it to be black in color
newcolors[1:30] = blue #If my scaler is between 1 and 30 I want it to be blue in color
newcolors[30:55] = yellow
newcolors[55:80] = grey
newcolors[80:] = red #Above 80 I want it to be red. The thing is I don't think these numbers actually represent the scalar values. But I would like it to.
newcmp = ListedColormap(newcolors) Got this idea from: |
Here's an example - the colormap needed a bit more work: import pyvista as pv
from pyvista import examples
from matplotlib.colors import ListedColormap
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np
pv.set_plot_theme('doc')
mesh = examples.download_st_helens()
mesh['values'] = pv.plotting.normalize(mesh['Elevation']) * 100 # Make the custom colormap
blue = np.array([12/256, 238/256, 246/256, 1])
black = np.array([11/256, 11/256, 11/256, 1])
grey = np.array([189/256, 189/256, 189/256, 1])
yellow = np.array([255/256, 247/256, 0/256, 1])
red = np.array([1,0,0,1])
mapping = np.linspace(mesh['values'].min(), mesh['values'].max(), 256)
newcolors = np.empty((256, 4))
newcolors[mapping >= 80] = red
newcolors[mapping < 80] = grey
newcolors[mapping < 55] = yellow
newcolors[mapping < 30] = blue
newcolors[mapping < 1] = black
mycolormap = ListedColormap(newcolors)
# Plot with Matplotlib for a sanity check
image = mesh['values'].reshape(mesh.dimensions[:2], order='f')
plt.pcolormesh(image, cmap=mycolormap)
plt.colorbar() # Plot with PyVista in 3D!
mesh.warp_by_scalar('Elevation').plot(scalars='values', cmap=mycolormap) |
Please note that you likely won't be able to plot your mesh with Matplotlib - that only works if the input dataset is a 2D |
FYI: I added this to the example gallery: https://docs.pyvista.org/examples/02-plot/cmap.html#custom-made-colormaps |
would you know how can fix the issue to normalize my data? The line "mesh['values'] = pv.plotting.normalize(mesh['Elevation']) * 100" keeps giving the error: module 'pyvista.plotting' has no attribute 'normalize' |
Hm - you must be on an older version of PyVista. That's a simple function that you could just copy/paste: def normalize(x, minimum=None, maximum=None):
if minimum is None:
minimum = np.nanmin(x)
if maximum is None:
maximum = np.nanmax(x)
return (x - minimum) / (maximum - minimum) But note that you will not need that normalizing function when you do this with your data - I simply used that to make an example with similar ranges to yours. |
Thanks Bane, that was really helpful! |
Greetings! I had a difficulty with trying to find a way to set ranges for a scalar for a 3-D object. For example for a 3D grid the z values would be the scalar and if my minimum and maximum values are 2000 to 10,000, can I make lets say, 2000-4000 red in color, 4000-5000 a green in color and etc...?
As far as I know, I know that you can change the color map pretty easily by using plotter.addmesh(cmap = 'color'), and you can set the overall range also pretty easily by using the plotter.update_scalar_bar_range(clim=[0,10000]).
Could you guys have any feedback on this? Thank you!
The text was updated successfully, but these errors were encountered: