You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ggplot绘制日期-收益率热力图失败求助:两类数据如何实现?

问题描述

我想要在R中使用ggplot绘制热力图,要求X轴为日期、Y轴为收益率。我通过quantmod导出BTC-USD股票数据并计算了日收益率,代码如下:

library(quantmod)
library(zoo)
library(ggplot2)
library(dplyr)

test1=getSymbols("BTC-USD",auto.assign=F)
test2=dailyReturn(test1)
test2=test2%>%fortify.zoo()%>%mutate(dr=daily.returns*100)
fig1=ggplot(data=test2,aes(x=Index,y=dr,fill=dr))+geom_tile()

运行上述代码后得到了空图,而我期望得到Y轴范围在-1.5到1.5的热力图。请问仅用日期和收益率这两类数据如何实现该热力图?

解决方案

你得到空图的核心原因是:geom_tile()需要每个坐标位置有明确的区块范围,但你的y=dr是连续的日收益率数值,每个日期对应的收益率都是独立单点,没有纵向区块宽度,所以tile无法被渲染出来。

要实现目标热力图,需要把连续的收益率分箱(binning),将Y轴转为离散区间,再基于日期-收益率区间的对应关系绘图,具体代码和说明如下:

library(quantmod)
library(zoo)
library(ggplot2)
library(dplyr)

# 获取数据并预处理
test1 <- getSymbols("BTC-USD", auto.assign = F)
test2 <- dailyReturn(test1) %>%
  fortify.zoo() %>%
  mutate(
    dr = daily.returns * 100,
    # 把收益率按-1.5到1.5的范围分箱,这里分成30个区间(可按需调整数量)
    dr_bin = cut(
      dr,
      breaks = seq(-1.5, 1.5, length.out = 31),
      include.lowest = TRUE,
      ordered_result = TRUE
    )
  ) %>%
  # 过滤超出目标范围的极端收益率
  filter(dr >= -1.5 & dr <= 1.5)

# 绘制热力图
fig1 <- ggplot(test2, aes(x = Index, y = dr_bin, fill = dr)) +
  geom_tile(height = 1) + # 设定tile高度匹配分箱间隔,避免空隙
  scale_fill_gradient2(low = "darkblue", mid = "white", high = "darkred", midpoint = 0) +
  labs(x = "日期", y = "收益率(%)", fill = "收益率(%)") +
  theme_minimal()

print(fig1)

关键细节说明

  • cut()函数将连续收益率转为离散区间,让Y轴具备可显示的区块维度
  • height=1确保每个tile高度刚好匹配分箱区间大小,保证视觉上的连续感
  • scale_fill_gradient2用蓝-白-红渐变区分负收益、零收益和正收益,更直观展示收益波动
  • 若想保留超出-1.5到1.5的极端值,可修改cut()的breaks参数为c(-Inf, seq(-1.5, 1.5, length.out = 29), Inf),把极端值归到首尾区间

内容的提问来源于stack exchange,提问作者Restu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 22:33:23