Matplotlib中plot_surface()的facecolors参数失效:无法实现3D曲面图的交替颜色显示
解决matplotlib plot_surface仅显示单一颜色的问题
我刚帮你排查了这个问题,核心原因是matplotlib的plot_surface对facecolors参数的格式要求和你想的不一样——它不接受直接传入字符串形式的颜色名数组,这就是为什么你只看到红色的原因。
问题根源
你生成的棋盘格字符串数组虽然在控制台输出正确,但plot_surface无法正确解析这种字符串格式的颜色输入,内部处理时只会默认取数组中的第一个颜色值(也就是红色)来渲染所有曲面片,所以整个曲面都变成了红色。
解决方案:把颜色字符串转为数值型RGB/RGBA数组
我们需要将"red"、"blue"这样的颜色名转换成matplotlib能识别的数值格式(0到1之间的浮点数数组),可以用matplotlib.colors.to_rgba函数来完成这个转换:
修改颜色数组生成代码
from matplotlib import colors as mcolors colortuple = ("red", "blue") # 先把颜色字符串转成RGBA数值数组 color_map = [mcolors.to_rgba(color) for color in colortuple] # 生成棋盘格样式的RGBA数组,最终形状为(251, 251, 4) colors = array([ array([color_map[int((xn + yn) % len(colortuple))] for xn in xrange]) for yn in xrange ])
修改后的colors数组每个元素都是一个包含4个浮点数的RGBA数组(比如红色是(1.0, 0.0, 0.0, 1.0)),完全符合plot_surface对facecolors的要求。
完整可运行代码
把这段修改整合到你的代码中,完整版本如下:
from matplotlib.ticker import LinearLocator from matplotlib import pyplot as plt from matplotlib import colors as mcolors from numpy import pi, sin, array, meshgrid, zeros, linspace # Constants xmax = 250 xrange = range(xmax + 1) c = 20.0 dx = 1 / xmax dt = 0.05 / xmax k = 4 * pi multiplier = (c * c * dt * dt / (dx * dx)) # Position and Time Steps. xsteps = linspace(0, 1, xmax + 1) tsteps = linspace(0, xmax * dt, xmax + 1) # Function Psi psi = zeros(shape=(len(xrange), len(xrange))) psi[0] = array([ 0 if (xn == 0 or xn == xmax) else 5 * sin(k * xsteps[xn]) for xn in xrange ]) psi[1] = array([ 0 if (xn == 0 or xn == xmax) else 5 * sin(k * xsteps[xn]) + multiplier * (2.5 * sin(k * xsteps[xn - 1]) + 2.5 * sin(k * xsteps[xn + 1]) - 5 * sin(k * xsteps[xn])) for xn in xrange ]) for tn in range(1, xmax): psi[tn + 1] = array([ 0 if (xn == 0 or xn == xmax) else 2 * psi[tn, xn] - psi[tn - 1, xn] + multiplier * (psi[tn, xn - 1] + psi[tn, xn + 1] - 2 * psi[tn, xn]) for xn in xrange ]) # Setting the parameters for plotting via matplotlib axes = plt.figure().add_subplot(projection="3d") (x, y) = meshgrid(xsteps, tsteps) # 修正颜色数组:转换为RGBA数值格式 colortuple = ("red", "blue") color_map = [mcolors.to_rgba(color) for color in colortuple] colors = array([ array([color_map[int((xn + yn) % len(colortuple))] for xn in xrange]) for yn in xrange ]) # Plotting function. axes.plot_surface(x, y, psi, facecolors=colors) # Customize the z axis. axes.zaxis.set_major_locator(LinearLocator(6)) axes.set_xlabel(r"$x\,[\mathrm{m}]$") axes.set_ylabel(r"$t\,[\mathrm{s}]$") axes.set_zlabel(r"$\psi\,(x,t)$") plt.tight_layout() plt.show()
运行这段代码后,你就能看到红、蓝交替的棋盘格3D曲面了。
内容的提问来源于stack exchange,提问作者LeoU
相关产品推荐
相关产品推荐

