You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib plot_surface自定义facecolors报错,仅支持基础颜色?

Fixing Matplotlib 3D Surface Face Color Truncation Issue

The root of your problem lies in how NumPy handles string arrays by default. When you create colors = np.empty(X.shape, dtype=str), NumPy defaults to a single-character Unicode string dtype (U1). This means any longer color name or hex code gets truncated to its first character, which is why you see errors like Invalid RGBA argument: '#' or 'o'—those are the first characters of your truncated color values.

Solution: Use a Flexible String Dtype

Change the dtype of your colors array to either:

  1. dtype=object: Stores full Python strings of any length (most flexible)
  2. A fixed-length string dtype like dtype='U20': Accommodates color names or hex codes up to 20 characters

Here's how to update your code for both scenarios:


Example 1: Using Hex Codes

import matplotlib.pyplot as plt
from matplotlib.ticker import LinearLocator
import numpy as np

fig = plt.figure()
ax = fig.gca(projection='3d')

# Make data
X = np.arange(-5, 5, 0.25)
xlen = len(X)
Y = np.arange(-5, 5, 0.25)
ylen = len(Y)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)

# Create color array with object dtype to store full hex codes
colortuple = ('#ff7f0e', '#2ca02c')
colors = np.empty(X.shape, dtype=object)  # This is the key fix!
for y in range(ylen):
    for x in range(xlen):
        colors[x, y] = colortuple[(x + y) % len(colortuple)]

# Plot the surface
surf = ax.plot_surface(X, Y, Z, facecolors=colors, linewidth=0)

# Customize z-axis
ax.set_zlim(-1, 1)
ax.zaxis.set_major_locator(LinearLocator(6))

plt.show()

Example 2: Using Full Color Names

import matplotlib.pyplot as plt
from matplotlib.ticker import LinearLocator
import numpy as np

fig = plt.figure()
ax = fig.gca(projection='3d')

# Make data
X = np.arange(-5, 5, 0.25)
xlen = len(X)
Y = np.arange(-5, 5, 0.25)
ylen = len(Y)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)

# Create color array with object dtype to store full color names
colortuple = ('gray', 'orange')
colors = np.empty(X.shape, dtype=object)  # Key fix here too!
for y in range(ylen):
    for x in range(xlen):
        colors[x, y] = colortuple[(x + y) % len(colortuple)]

# Plot the surface
surf = ax.plot_surface(X, Y, Z, facecolors=colors, linewidth=0)

# Customize z-axis
ax.set_zlim(-1, 1)
ax.zaxis.set_major_locator(LinearLocator(6))

plt.show()

Alternative Approach: Use RGBA Arrays

If you prefer, you can convert your color strings directly to RGBA arrays using matplotlib.colors.to_rgba, which avoids string truncation entirely:

from matplotlib.colors import to_rgba

# Convert color tuple to RGBA values
colortuple = (to_rgba('#ff7f0e'), to_rgba('#2ca02c'))
colors = np.empty(X.shape + (4,), dtype=np.float32)  # 4 channels for RGBA
for y in range(ylen):
    for x in range(xlen):
        colors[x, y] = colortuple[(x + y) % len(colortuple)]

This approach is more explicit and avoids any string-related issues, but requires creating a 3D array for RGBA values.

内容的提问来源于stack exchange,提问作者ch.A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 18:28:08