如何绘制时间序列散点图,将缺失的 y 轴值显示为间隙?

Posted

技术标签:

【中文标题】如何绘制时间序列散点图,将缺失的 y 轴值显示为间隙?【英文标题】:How to plot a time-series scatterplot showing missing y-axis values as gaps? 【发布时间】:2021-10-22 06:24:03 【问题描述】:

我正在尝试创建一个散点图,其中 x 轴为日期/时间,y 轴为盐度。但是,由于设备故障,有些日期/时间点没有盐度值,但我仍然需要这些时间部分显示在我的图表上,以帮助解释我正在查看的生态模式。谁能建议如何在图表上显示这些缺失的部分?

我当前的数据代码和未显示缺失值的绘图。

编辑 我的数据有明确的缺失值,其中数据由于记录器错误而被删除,但被列为“NA”(见图)。不幸的是,我每半小时收集数千个数据点,因此很难显示所有数据。

Screenshot of data showing 'NA' values

OY1_AllTimes <- read_csv("~/Documents/TAMUG_Thesis/Rollover_Pass_Data/Logger/RP_LoggerData_OY1_AllTimes.csv")
summary(OY1_AllTimes)

OY1_AllTimes$Date_time<-paste(OY1_AllTimes$Date, OY1_AllTimes$Time)
summary(OY1_AllTimes$Date_time)

date_time_OY1_AllTimes<-as.POSIXct(OY1_AllTimes$Date_time, format="%m/%d/%Y %H:%M")
date_time_OY1_AllTimes
date_time2_OY1_AllTimes<-as.factor(date_time_OY1_AllTimes)
date_time2_OY1_AllTimes
summary(OY1_AllTimes)

Summary of OY1_AllTimes

p_OY1_AllTimes <- ggplot(data = OY1_AllTimes, aes(x=date_time2_OY1_AllTimes, y=Salinity)) + geom_point() + theme_classic()+
  scale_x_discrete("Date", breaks=c("0019-10-04 09:30:00", "0019-11-01 05:00:00", "0019-12-01 00:00:00", "0020-01-01 00:00:00", "0020-02-01 00:00:00",
                                    "0020-03-01 00:00:00","0020-04-01 00:00:00", "0020-05-01 00:00:00", "0020-06-01 00:00:00"),
                   labels=c("10/2019", "11/2019", "12/2019", "1/2020", "2/2020", "3/2020", "4/2020", "5/2020", "6/2020"))+ylab("Salinity")+ggtitle("OY1")
p_OY1_AllTimes

Scatterplot of OY1 without missing values

基本上我希望看​​到上面的散点图,其中的间隙表示没有盐度数据的时期,以便日期/时间尺度是连续的。

数据的子样本:

# A tibble: 50 x 5
   Site  Date    Time   Salinity Date_time       
   <chr> <chr>   <time>    <dbl> <chr>           
 1 OY1   10/4/19 09:30    NA     10/4/19 09:30:00
 2 OY1   10/4/19 10:00    NA     10/4/19 10:00:00
 3 OY1   10/4/19 10:30     0.891 10/4/19 10:30:00
 4 OY1   10/4/19 11:00     0.961 10/4/19 11:00:00
 5 OY1   10/4/19 11:30     1.02  10/4/19 11:30:00
 6 OY1   10/4/19 12:00     1.10  10/4/19 12:00:00
 7 OY1   10/4/19 12:30     1.19  10/4/19 12:30:00
 8 OY1   10/4/19 13:00     1.27  10/4/19 13:00:00
 9 OY1   10/4/19 13:30     1.33  10/4/19 13:30:00
10 OY1   10/4/19 14:00     1.42  10/4/19 14:00:00
# … with 40 more rows```

【问题讨论】:

我认为您应该使用date_time_OY1_AllTimes 变量而不是转换后的因子版本,并删除scale_x_discrete。然后你应该得到一个基于底层时间戳的连续日期轴,而不是按顺序堆叠。 @JonSpring 不幸的是,这仍然会生成一个删除我所有“NA”数据的图表。我需要将这些显示为时间序列中的空白。 你能解释一下“将这些显示为间隙”是什么意思吗?这是否意味着您想要每个缺失点的轴上的文本?我原以为我下面的答案是“显示差距”,时间轴上有一个部分缺少点,但也许我还不明白。 @JonSpring 所以我想要你上面显示的内容,但是当我尝试这样做时,R 仍在删除我的缺失值的行并给我其他错误。我成功地为第一个图表运行了您的代码,但收到了警告消息:删除了包含缺失值 (geom_point) 的 3831 行。对于您的第二张图,我收到一个未使用的争论(data_labels =“%b\n'%y”)的错误。对于您的第三张图,我收到错误“中断”和“标签”必须具有相同的长度。 您看到的警告是因为您的数据在 ggplot 中用于 3831 行数据的至少一列中包含 NA。如果这是您所期望的,那可能会很好。如果您的 Date_time 列不是日期时间数据(通常是 POSIXct),则可能会出现第二个错误。也许是性格或因素数据? (什么是str(OY1_AllTimes$Date_time))?在任何情况下,如果您可以在问题中包含代码形式的数据样本,那么提供帮助会更容易,如下所述:***.com/questions/5963269/… 【参考方案1】:

这是我尝试用一​​些我们都可以运行的可重现代码来证明这一点。

这里有一些任意的假数据。重要的是它在时间戳上有很大的差距,因为我从 100:399 中删除了几百行。此时,timestamp 被存储为日期时间数据,在最典型的“POSIXct”变体中,与您的date_time_OY1_AllTimes 变量相同。

set.seed(42)
my_fake_data <- data.frame(timestamp = as.POSIXct("2021-01-01 00") + cumsum(runif(1000, 0, 6E4)), reading = cumsum(rnorm(1000)))
my_fake_data <- my_fake_data[c(1:99, 400:1000),]

ggplot2 中的典型情况是使用该 POSIXct 值进行绘图。你会看到差距。 ggplot2 将时间戳映射到 x 轴,并为我们选择默认标签。

ggplot(my_fake_data, aes(timestamp, reading)) +
  geom_point() 

如果我们想要每月标签,我们可以指定它以及我们想要查看的格式:

... + scale_x_datetime(date_breaks = "month", 
                       date_labels = "%b\n'%y", minor_breaks = NULL)

在您的示例中,时间戳已转换为因子,这保留了它们的顺序,但它会及时将它们从上下文中删除,因此间隙已经消失。在这里,我手动添加了离散标签,但它们与我的数据点不再有明确的时间关系。我可以让他们说出我想说的任何内容,除非我手动调整它们,否则它们会出错。

ggplot(my_fake_data, aes(as.factor(timestamp), reading)) +
  geom_point() +
  scale_x_discrete(breaks = as.factor(my_fake_data[1+100*0:7,1]),
                   labels = format(
                     seq.Date(as.Date("2021-01-01"), 
                              as.Date("2021-08-01"), by = "month"), "%b %Y"))

【讨论】:

【参考方案2】:

很难说出您的数据的真实情况,我假设您有一个隐式缺失数据问题。

这意味着,您有一个缺少观察的 data.frame/time 序列。但问题是,这些缺失值并未明确作为 NA 给出。相反,这些都被忽略了。

具有 NA 的时间序列如下所示:

1.1.2021 14:00
1.1.2021 15:00
1.1.2021 16:00
1.1.2021 17:00
1.1.2021 NA
1.1.2021 19:00

我猜你的问题是这样的:

1.1.2021 14:00
1.1.2021 15:00
1.1.2021 16:00
1.1.2021 17:00
1.1.2021 19:00

所以不同的是,18:00 时间步没有 NA 值。但是,你当然知道有一个缺失值(这就是为什么它被称为隐式缺失值)。

假设您有一个规则间隔的时间序列(即以规则间隔测量的值,例如 1h),您可以使用 tsibble 包将隐式缺失值转换为正常缺失值,其中您有NAs 是系列。

这是一个简单的例子(因为我没有你的数据):

library("tsibble")

# Read in your data as tsibble
data_example <- tsibble(
  year = c(2016, 2017, 2018, 2019, 2021, 2022),
  measure = sample(1:10, size = 6),
  index = year
)

# Take a look at the data
data_example

# Use the fill_gaps function of tsibble
data_na <- fill_gaps(data_example, .full = TRUE)

# You can see now, the implicit missing year 2020 is now added as NA  
data_na

当然,您也可以对各种不同的规则间隔时间序列数据(15 秒、分钟、小时、月...)执行此操作。您只需在创建 tsibble 对象时定义时间步。

现在绘图很容易:

library("ggplot2")
ggplot(data = data_na) + geom_point( aes(year, measure))

这会给你这个情节:

如您所见,如您所愿,该系列已绘制,但情节中没有 2020 年。如果您想更加关注缺失的数据,还可以使用 imputeTS 包。

library("imputeTS")
ggplot_na_distribution(data_na)

这将如下所示:

这只是一个小的示例时间序列,对于更大的时间序列,这看起来像例如这个情节:

【讨论】:

抱歉不清楚,实际上我的 R 数据中有明确的缺失值显示为“NA”(我将在上面附上一张照片)。但是,当我尝试绘制这些 R 时,仍然会删除包含缺失值的行。在这种情况下 tsibble 还能用吗?

以上是关于如何绘制时间序列散点图,将缺失的 y 轴值显示为间隙?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用散点图显示间隙

power bi怎么做散点图啊?如何利用power bi绘制散点图??

eviews怎么做散点图

python 绘制三维图形、三维数据散点图

散点图绘制

用seaborn绘制散点图