Python 使用对数刻度绘制 mplot3d/axes3D xyz 曲面图?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3909794/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Plotting mplot3d / axes3D xyz surface plot with log scale?
提问by Mark
I've been looking high and low for a solution to this simple problem but I can't find it anywhere! There are a loads of posts detailing semilog / loglog plotting of data in 2D e.g. plt.setxscale('log') however I'm interested in using log scales on a 3d plot(mplot3d).
我一直在寻找解决这个简单问题的方法,但在任何地方都找不到!有很多帖子详细介绍了 2D 中数据的 semilog/loglog 绘图,例如 plt.setxscale('log') 但是我对在 3d plot(mplot3d) 上使用对数刻度很感兴趣。
I don't have the exact code to hand and so can't post it here, however the simple example below should be enough to explain the situation. I'm currently using Matplotlib 0.99.1 but should shortly be updating to 1.0.0 - I know I'll have to update my code for the mplot3d implementation.
我手头没有确切的代码,所以不能在这里发布,但是下面的简单示例应该足以解释这种情况。我目前正在使用 Matplotlib 0.99.1,但很快就会更新到 1.0.0 - 我知道我必须更新我的 mplot3d 实现代码。
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FixedLocator, FormatStrFormatter
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = Axes3D(fig)
X = np.arange(-5, 5, 0.025)
Y = np.arange(-5, 5, 0.025)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.jet, extend3d=True)
ax.set_zlim3d(-1.01, 1.01)
ax.w_zaxis.set_major_locator(LinearLocator(10))
ax.w_zaxis.set_major_formatter(FormatStrFormatter('%.03f'))
fig.colorbar(surf)
plt.show()
The above code will plot fine in 3D, however the three scales (X, Y, Z) are all linear. My 'Y' data spans several orders of magnitude (like 9!), so it would be very useful to plot it on a log scale. I can work around this by taking the log of the 'Y', recreating the numpy array and plotting the log(Y) on a linear scale, but in true python style I'm looking for smarter solution which will plot the data on a log scale.
上面的代码可以在 3D 中很好地绘制,但是三个尺度(X、Y、Z)都是线性的。我的“Y”数据跨越了几个数量级(比如 9!),所以在对数刻度上绘制它会非常有用。我可以通过获取“Y”的日志、重新创建 numpy 数组并在线性刻度上绘制 log(Y) 来解决此问题,但在真正的 Python 风格中,我正在寻找更智能的解决方案,它将数据绘制在一个对数刻度。
Is it possible to produce a 3D surface plot of my XYZ data using log scales, ideally I'd like X & Z on linear scales and Y on a log scale?
是否可以使用对数标度生成我的 XYZ 数据的 3D 曲面图,理想情况下我希望 X 和 Z 在线性标度上,Y 在对数标度上?
Any help would be greatly appreciated. Please forgive any obvious mistakes in the above example, as mentioned I don't have my exact code to have and so have altered a matplotlib gallery example from my memory.
任何帮助将不胜感激。请原谅上面示例中的任何明显错误,如前所述,我没有确切的代码,因此根据我的记忆更改了 matplotlib 库示例。
Thanks
谢谢
回答by Alejandro
All you have to do is to define the scale of the axis you want. For instance, if you want that x and y axis are on log scale, you should write:
你所要做的就是定义你想要的轴的比例。例如,如果您希望 x 和 y 轴在对数刻度上,您应该编写:
ax.xaxis.set_scale('log')
ax.yaxis.set_scale('log')
and eventually:
并最终:
ax.zaxis.set_scale('log')
回答by Andreas Wilkes
Since I encountered the same question and Alejandros answer did not produced the desired Results here is what i found out so far.
由于我遇到了同样的问题,而 Alejandros 的回答没有产生预期的结果,这是我目前发现的结果。
The log scaling for Axes in 3D is an ongoing issue in matplotlib. Currently you can only relabel the axes with:
3D 轴的对数缩放是 matplotlib 中的一个持续问题。目前,您只能使用以下内容重新标记轴:
ax.yaxis.set_scale('log')
This will however not cause the axes to be scaled logarithmic but labeled logarithmic.
ax.set_yscale('log')will cause an exception in 3D
然而,这不会导致轴被缩放为对数,而是标记为对数。
ax.set_yscale('log')将导致 3D 异常
See on github issue 209
请参阅 github问题 209
Therefore you still have to recreate the numpy array
因此,您仍然必须重新创建 numpy 数组
回答by Gil Hiram
in osx: ran ax.zaxis._set_scale('log') (notice the underscore)
在 osx 中:运行 ax.zaxis._set_scale('log') (注意下划线)
回答by Pablo riera hernandez
There is no solution because of the issue 209. However, you can try doing this:
由于问题209,没有解决办法。但是,您可以尝试这样做:
ax.plot_surface(X, np.log10(Y), Z, cmap='jet', linewidth=0.5)
If in "Y" there is a 0, it is going to appear a warning but still works. Because of this warning color maps don′t work, so try to avoid 0 and negative numbers. For example:
如果在“Y”中有一个 0,它将出现警告但仍然有效。因为这个警告色图不起作用,所以尽量避免 0 和负数。例如:
Y[Y != 0] = np.log10(Y[Y != 0])
ax.plot_surface(X, Y, Z, cmap='jet', linewidth=0.5)

