这个等高线图是用Igor程序制作的,它在大气化学和污染研究中很受欢迎:
我该如何使我的图表看起来更像Igor的图表?
请注意,我提出的这些其他问题与重新创建此图表的任务密切相关:
- geom_raster插值对数比例尺 - 用于类别的2d密度图
在我提出这个问题之后,我一直在更新R代码的gist,将这些问题的答案详细介绍,并成功地复制了这些图表(gist中包含示例输出)。该gist在这里: https://gist.github.com/benmarwick/9a54cbd325149a8ff405。
我正在尝试用R重新创建它,为了一个想停止使用Igor的朋友,但我们还无法完全做到。这里是数据集(与使用Igor制作图表所使用的相同数据),以及我目前在使用R制作图表方面所做的:
# read in the data
dat <- read.csv("contour_plot_data.csv")
# focus on the untransformed values
dat <- dat[, 1:108]
# get Diameter value from col names
Diameter <- as.numeric(gsub("X", "", names(dat)[-1]))
# interpolate between the Diameter values for a smoother contour,
# a seperate interpolation for each row (date value)
# this takes a moment or two...
interp <- seq(min(Diameter), max(Diameter), 0.2)
dat_interp <- data.frame(matrix(0, ncol = length(interp), nrow = nrow(dat)))
for(i in 1:nrow(dat)){
# get the values from row i
vec <- unlist(dat[i, 2:108], use.names = FALSE)
# compute loess interpolations
lo <- loess(vec ~ Diameter)
# predict interpolated values
pr <- predict(lo, newdata = data.frame(Diameter = interp))
# store in a data frame
df <- data.frame(ct = unname(pr), Diameter = interp)
# add as new row to new data frame
dat_interp[i, ] <- df$ct
print(i) # so we can see that it's working
}
# add date col and col names to the interpolated data
names(dat_interp) <- interp
dat_interp$date <- as.character(dat$Time)
# melt data into long format
# see http://www.cookbook-r.com/Manipulating_data/Converting_data_between_wide_and_long_format/
library(tidyr)
gather_cols <- interp
dat_long <- gather_(dat_interp, "Diameter", "dN_dlogDp", gather_cols)
# we want diameter as a numeric
dat_long$Diameter <- as.numeric(as.character(dat_long$Diameter))
# we want date as a date format
x <- as.character(dat_long$date)
date_ <- as.Date(x, format = "%d/%m/%Y")
time_ <- gsub(" ", "", substr(x, nchar(x) - 4, nchar(x)))
dat_long$date_time <- as.POSIXct(paste0(date_, " ", time_))
# The Igor plot seems to use log dN_dlogDp values, so let's get those
dat_long$dN_dlogDp_log <- log10(dat_long$dN_dlogDp)
dat_long$dN_dlogDp_log <- ifelse(dat_long$dN_dlogDp_log == "NaN", 0, dat_long$dN_dlogDp_log)
# get on with plottong...
library(ggplot2)
library(scales)
labels_breaks <- seq(0, max(Diameter), 100)
mytheme <- theme_bw(base_size = 14) + theme(aspect.ratio = 1/4)
ggplot(dat_long, aes(y = Diameter, x = date_time, fill=dN_dlogDp_log)) +
geom_raster(interpolate = TRUE) +
scale_fill_gradientn(name=expression(log(dN/dlogD[p])), colours = rainbow(7)) +
scale_y_continuous(expand = c(0,0), breaks = labels_breaks ) +
scale_x_datetime(expand = c(0,0), breaks = date_breaks("12 hours")) +
ylab("Diameter (nm)") +
xlab("Date and time") +
mytheme
我的图表需要更精细的标签和刻度线等。然而,我的主要问题是为什么我的填充轮廓看起来与Igor的图表如此不同。比例似乎被反转了,插值看起来非常不同。我该如何使我的图表看起来更像Igor的图表?
请注意,我提出的这些其他问题与重新创建此图表的任务密切相关:
- geom_raster插值对数比例尺 - 用于类别的2d密度图
在我提出这个问题之后,我一直在更新R代码的gist,将这些问题的答案详细介绍,并成功地复制了这些图表(gist中包含示例输出)。该gist在这里: https://gist.github.com/benmarwick/9a54cbd325149a8ff405。
更新:我现在已经制作了一个能够生成这些图的软件包:https://github.com/benmarwick/smps
scale_fill_gradientn(colours = rev(rainbow(7))
。要忠实地重新创建它,您需要了解该颜色比例的详细信息。过渡似乎非常锐利,所以我不确定是否值得详细重现。我建议使用viridis
包中的scale_fill_viridis
。 - Axeman