R语言中image()函数为何未使用指定颜色绘制测井相?
R语言绘制测井相时颜色不匹配问题解析
需求背景
需要在R语言中绘制测井相,数据包含一列名为LFC的整数列(取值0-4),对应关系为:
- LFC=0: undef
- LFC=1: brine sand
- LFC=2: oil sand
- LFC=3: gas sand
- LFC=4: shale
Python实现代码及效果
import numpy as np import matplotlib.pyplot as plt import pandas as pd import matplotlib.colors as colors logs = pd.read_csv('data/proyectoFinal/well_log.csv') ccc = ['#B3B3B3','blue','green','red','#996633',] cmap_facies = colors.ListedColormap(ccc[0:len(ccc)], 'indexed') cluster=np.repeat(np.expand_dims(logs['LFC'].values,1), 100, 1) im=plt.imshow(cluster, interpolation='none', aspect='auto',cmap=cmap_facies,vmin=0,vmax=4) cbar=plt.colorbar(im) cbar.set_label((12*' ').join(['undef', 'brine', 'oil', 'gas', 'shale'])) cbar.set_ticks(range(0,1)); cbar.set_ticklabels('')

R语言实现代码及问题
logs <- read.csv('data/proyectoFinal/well_log.csv') ccc <- c('#B3B3B3', 'blue', 'green', 'red', '#996633') cluster <- matrix(rep(logs$LFC, each = 100), nrow = 100) colores <- as.vector(ccc) image(t(cluster), col = colores, axes = FALSE, xlab = "", ylab = "") axis(2, at = seq(1, nrow(cluster), length.out = length(ccc)), labels = c('undef', 'brine', 'oil', 'gas', 'shale')) axis(1, at = seq(1, ncol(cluster), length.out = 10), labels = FALSE) box()

疑问:为何R语言中image()函数使用的颜色与我指定的颜色不一致?
问题原因及解决方法
R的image()函数默认会把输入矩阵的最小值映射到颜色向量的第一个值、最大值映射到最后一个值,但会自动将数据区间均匀分割成与颜色数量一致的分段。而你的LFC是0-4的整数,加上矩阵转置后的顺序错位,导致颜色映射出现偏差。
核心问题有两点:
- 颜色映射的数值匹配逻辑:默认映射是线性分割数据区间,没有让每个
LFC整数直接对应颜色向量的对应位置; - 矩阵转置与坐标轴方向:转置操作打乱了数据的原始顺序,加上
image()的坐标轴绘制逻辑,进一步放大了颜色错位的问题。
修改后的R代码如下:
logs <- read.csv('data/proyectoFinal/well_log.csv') ccc <- c('#B3B3B3', 'blue', 'green', 'red', '#996633') # 按原数据顺序构造矩阵,避免转置导致的顺序混乱 cluster <- matrix(rep(logs$LFC, each = 100), ncol = 100, byrow = FALSE) # 设置分段断点,让每个LFC整数对应独立区间 breaks <- seq(-0.5, 4.5, 1) # 指定breaks参数,确保每个LFC值准确映射对应颜色 image(cluster, col = ccc, axes = FALSE, xlab = "", ylab = "", breaks = breaks) # 按image默认坐标范围[0,1]设置坐标轴标签位置 axis(2, at = seq(0, 1, length.out = length(ccc)), labels = c('undef', 'brine', 'oil', 'gas', 'shale')) axis(1, at = seq(0, 1, length.out = 10), labels = FALSE) box()
代码说明:
breaks = seq(-0.5,4.5,1):为每个LFC整数划分独立区间(如0对应[-0.5,0.5]),确保整数与颜色向量的索引完全对应;- 调整矩阵构造方式并取消不必要的转置,保证数据顺序与视觉展示一致;
- 坐标轴标签的
at参数适配image()默认的[0,1]坐标范围,让标签与对应颜色区域匹配。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

