Matplotlib quiver绘制Fluent插值速度数据时箭头全黑问题排查
问题解决:Matplotlib Quiver箭头颜色不显示(始终黑色)
问题原因
你的箭头始终显示为黑色,核心原因有两个:
- Matplotlib的
quiver函数默认会给箭头添加黑色边缘线,当你将矢量归一化后箭头尺寸很小,边缘线会完全覆盖填充色,导致看起来全黑。 - 未添加颜色条,无法直观验证颜色映射是否生效。
解决步骤
- 给
quiver添加edgecolor='face'参数,让箭头边缘颜色与填充色一致;或者设置linewidth=0直接移除边缘线。 - 使用已插值得到的
v_mag_interpol作为颜色数据(无需重复计算r,避免冗余)。 - 添加颜色条,关联当前子图的quiver对象,展示颜色与速度幅值的对应关系。
修改后的关键代码
# Plot interpolated data with normalized vectors and normalized colormap # 直接使用已插值的速度幅值v_mag_interpol作为颜色数据 u_norm = v_x_interpol / v_mag_interpol v_norm = v_y_interpol / v_mag_interpol # 创建quiver对象,设置边缘颜色与填充色一致 q = axs[3].quiver(xx_filtered, yy_filtered, u_norm, v_norm, v_mag_interpol, norm=matplotlib.colors.Normalize(vmin=np.min(v_mag_interpol), vmax=np.max(v_mag_interpol)), cmap='bwr', edgecolor='face') # 关键:让边缘颜色和填充色一致 # 添加颜色条,关联quiver对象 fig.colorbar(q, ax=axs[3], label='速度幅值')
完整修改后代码
import pandas as pd import numpy as np import scipy import matplotlib.pyplot as plt import matplotlib input_filename = 'period_rot_shadow_vel-mag-vel_comps.txt' df_results = pd.read_csv(input_filename, sep=',', skiprows=1, names=['nodenumber', 'X', 'Y', 'Z', 'vel_mag', 'v_x', 'v_y', 'v_z', 'v_ax', 'v_rad', 'v_tang']) x_data_min = df_results['X'].min() x_data_max = df_results['X'].max() y_data_min = df_results['Y'].min() y_data_max = df_results['Y'].max() x_size = np.abs(x_data_max) + np.abs(x_data_min) y_size = np.abs(y_data_max) + np.abs(y_data_min) rect_mesh_spacing = 0.001 N_x_steps = int(x_size/rect_mesh_spacing) + 1 N_y_steps = int(y_size/rect_mesh_spacing) + 1 rect_mesh_x_axis = np.array([]) rect_mesh_y_axis = np.array([]) for i in range(0, N_x_steps): x = x_data_min + i * rect_mesh_spacing rect_mesh_x_axis = np.append(rect_mesh_x_axis, x) for i in range(0, N_y_steps): y = y_data_min + i * rect_mesh_spacing rect_mesh_y_axis = np.append(rect_mesh_y_axis, y) # 使用meshgrid创建矩形网格 xx, yy = np.meshgrid(rect_mesh_x_axis, rect_mesh_y_axis) # 生成网格点数组 xy_mesh = np.array((xx,yy)).T # 定义输入数据坐标 input_coords = np.array(list(zip(df_results['X'].to_numpy(), df_results['Y'].to_numpy()))) # KDTree查找最近邻点 tree = scipy.spatial.KDTree(input_coords) dist, idx = tree.query(xy_mesh) # 过滤距离符合要求的网格点 radius = (rect_mesh_spacing + rect_mesh_spacing) / 2 distance_filter = dist <= radius xx_filtered, yy_filtered = xy_mesh[distance_filter].T # 插值速度分量和幅值 v_x_interpol= scipy.interpolate.griddata((df_results['X'], df_results['Y']), df_results['v_x'], (xx_filtered, yy_filtered), method = 'nearest') v_y_interpol= scipy.interpolate.griddata((df_results['X'], df_results['Y']), df_results['v_y'], (xx_filtered, yy_filtered), method = 'nearest') v_mag_interpol = scipy.interpolate.griddata((df_results['X'], df_results['Y']), df_results['vel_mag'], (xx_filtered, yy_filtered), method = 'nearest') # 创建子图 fig, axs = plt.subplots(1,4) fig.set_size_inches(13, 4) # 绘制原始数据 axs[0].quiver(df_results['X'], df_results['Y'], df_results['v_x'], df_results['v_y']) axs[0].set_title('原始数据') # 绘制插值后数据 axs[1].quiver(xx_filtered, yy_filtered, v_x_interpol, v_y_interpol) axs[1].set_title('插值后数据') # 绘制归一化矢量尺寸的插值数据 r = (v_x_interpol**2 + v_y_interpol**2)**0.5 axs[2].quiver(xx_filtered, yy_filtered, v_x_interpol/r, v_y_interpol/r) axs[2].set_title('归一化矢量尺寸') # 绘制带颜色映射的归一化矢量数据 u_norm = v_x_interpol / v_mag_interpol v_norm = v_y_interpol / v_mag_interpol q = axs[3].quiver(xx_filtered, yy_filtered, u_norm, v_norm, v_mag_interpol, norm=matplotlib.colors.Normalize(vmin=np.min(v_mag_interpol), vmax=np.max(v_mag_interpol)), cmap='bwr', edgecolor='face') fig.colorbar(q, ax=axs[3], label='速度幅值') axs[3].set_title('归一化矢量+颜色映射') plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者user2882635
相关产品推荐
相关产品推荐

