简体   繁体   中英

matplotlib plot_surface colormap does not scale with the z-axis

I try to make simple 3D plot with plot_surface of matplotlib, below is the minimum example:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
x_test = np.arange(0.001, 0.01, 0.0005)
y_test = np.arange(0.1, 100, 0.05)

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

Xtest, Ytest = np.meshgrid(x_test, y_test)

Ztest = Xtest**-1 + Ytest

surf = ax.plot_surface(Xtest, Ytest, Ztest,
                       cmap=cm.plasma, alpha=1,
                       antialiased=False)

fig.colorbar(surf, shrink=0.5, aspect=5)
ax.set_ylabel(r'$ Y $', fontsize=16)
ax.set_xlabel(r'$ X $', fontsize=16)
ax.set_zlabel(r'$ Z $', fontsize=16)

The result gives strange colormap, that does not represent the magnitude of the z scale, as you can see from here 3D plot result . I mean if you take a straight line of constant Z, you don't see the same color. I've tried to change the ccount and rcount inside plot_surface function or changing the interval of the Xtest or Ytest data, nothing helps. I've tried some suggestion from here and here . But it seems not related.

Could you help me how to solve this? It seems a simple problem, but I couldn't solve it. Thanks!

Edit

I add example but using the original equation that I don't write it here (it's complicated), please take a look: Comparison . While the left figure was done in Matlab (by my advisor), the right figure by using matplotlib. You can see clearly the plot on the left really make sense, the brightest color always on the maximum z-axis. Unfortunately, i don't know matlab. I hope i can do it by using python, Hopefully this edit makes it more clear of the problem.

Edit 2 I'm sure this is not the best solution. That's why I put it here, not as an answer. As suggested by @swatchai to use the contour3D . Since surface is set of lines, I can generate the correct result by plotting a lot of contour lines, by using:

surf = ax.contour3D(Xtest, Ytest, Ztest, 500, cmap=cm.plasma,
                 alpha=0.5, antialiased=False)

The colormap is correct as you can see from here alternative1 But the plot is very heavy. When you zoom-in, it doesn't look good, unless you increase again the number of the contour. Any suggestion are welcome :).

I don't know how this can be achieved but maybe some words on why this is happening. plot_surface generates a mesh where the vertices are defined by x and y and z . Each patch has 4 corners and gets a color corresponding to its z value. Looking at the plot it could be the maximal z value of the 4 corners (just a guess). And if you look closely the colors of the patches actually do get lighter as you move in +y direction. But what is far more obvious are the color changes in x direction, producing the slopes you mentioned.

But this can not be avoided if each patch has just a single color.

You can see this maybe more clearly if you change the formula to Z = (X**-1 + 10 * Y)

The behavior of the surface plot is not what you expect. Only contour3D or contourf3D can display such behavior. Here is relevant code that you can try to get the plot that follows:

surf = ax.plot_surface(Xtest, Ytest, Ztest, cmap=cm.plasma, alpha=0.55)
ax.contourf3D(Xtest, Ytest, Ztest, cmap=cm.plasma)

The plot that show both surface and contourf3D:

轮廓

I guess, the formal answer to plot this kind of surface is by using Axes3D.contour and Axes3D.contourf . Based on documentation , for example:

surf2 = ax.contourf(Xtest, Ytest, Ztest, 250, cmap=cm.plasma,
                    alpha=0.6, antialiased=False)
surf = ax.contour(Xtest, Ytest, Ztest, 250, cmap=cm.plasma,
                  alpha=0.6, antialiased=False)

The result is here . The colormap shows correct z-scale. It's not as perfect as smooth surface, as it depends on how much we zoom it or how much we put the contour. I don't know if there's a way to create this by plot_surface. thanks @swatchai.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM