基于CSV第四列值为3D散点分配颜色的技术问题及报错排查
问题解决思路与修正代码
错误原因
你写的散点图颜色赋值代码存在语法错误:
- 错误写法里把整数
0当成函数调用((0)(...)),这是导致TypeError: 'int' object is not callable的直接原因 - 参数名写错,应该是
c=而非col== - 颜色映射的逻辑实现方式不符合Python语法
解决方案
我们可以通过两种简单方式实现基于p列的颜色分配:
方法一:用numpy.where直接生成颜色数组
利用np.where根据p的取值(1或-1)直接生成对应的颜色列表:
colors = np.where(p == 1, 'g', 'r') ax.scatter(X, Y, np.log10(Z), c=colors, marker='o')
如果需要替换部分红点为其他颜色(比如蓝色),可以嵌套where:
# 示例:p=-1且Z>某个阈值时设为蓝色,否则红色;p=1时绿色 colors = np.where(p == 1, 'g', np.where(Z > 100, 'b', 'r')) ax.scatter(X, Y, np.log10(Z), c=colors, marker='o')
方法二:用字典映射颜色
先创建p值到颜色的映射字典,再通过列表推导生成颜色数组:
color_map = {1: 'g', -1: 'r'} # 如果要替换部分红点,可先修改p的部分值或调整映射逻辑 colors = [color_map[val] for val in p] ax.scatter(X, Y, np.log10(Z), c=colors, marker='o')
完整修正后的代码
from typing import Any import matplotlib from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt import numpy as np import pandas as pd import sys import csv import matplotlib.ticker as mticker # 导入CSV数据 csvData = [] with open('ParvaluesMESS.csv', 'r') as csvfile: csvReader = csv.reader(csvfile, delimiter=',') for csvRow in csvReader: csvData.append(csvRow) csvData = np.array(csvData).astype(float) X, Y, Z, p = csvData[:,0], csvData[:,1], csvData[:,2], csvData[:,3] # 绘图设置 fig = plt.figure(figsize=(5,5)) ax = fig.add_subplot(111, projection='3d') # 绘制trisurface cb = ax.plot_trisurf(X, Y, np.log10(Z), cmap='coolwarm', alpha=0.75) # 生成散点颜色:p=1为绿色,p=-1为红色 colors = np.where(p == 1, 'g', 'r') # 若需替换部分红点,比如Z>100的红点改为蓝色,可替换上面一行: # colors = np.where(p == 1, 'g', np.where(Z > 100, 'b', 'r')) ax.scatter(X, Y, np.log10(Z), c=colors, marker='o') # Z轴刻度格式化 def log_tick_formatter(val, pos=None): """重新格式化对数刻度显示""" return f"$10^{{{int(val)}}}$" ax.zaxis.set_major_formatter(mticker.FuncFormatter(log_tick_formatter)) # 颜色条与轴标签设置 fig.colorbar(cb, shrink=0.5) ax.set_title("First-year sea ice PAR") ax.set_xlabel("Ice Thickness m") ax.set_ylabel("Snow thickness m") ax.set_zlabel("µmol $^{m-2}$ $^{s-1}$") ax.view_init(azim=70, elev=30) ax.set_xlim3d(20, 350) # 保存与显示 image_format = 'png' image_name = 'test.eps' plt.show() fig.savefig(image_name, format=image_format, dpi=1200)
额外说明
- 移除了原代码中未使用的
csvFileName变量、bbox导入和ticklabels函数 - 散点颜色设置不会影响下方的trisurface,两者是独立的绘图元素
内容的提问来源于stack exchange,提问作者benjamin Redmond Roche
相关产品推荐
相关产品推荐

