使用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
相关产品推荐
相关产品推荐

