我需要在R中绘制市场概况(又称交易量概况)图表。
以上是我想要的示例。横轴是日期。在垂直轴上,我有水平仪。而且我还需要在每个日期和每个级别上都有一个水平条,以显示音量(右边的条)和计数(左边的条)。
我的数据如下所示。我有一个日期和级别列,我想用于组和数量以及要显示为值的数量。
date level volume count
1: 2019-03-04 00:00:00 0.4 50193087 51
2: 2019-03-04 00:00:00 0.1 30030902 50
3: 2019-03-04 00:00:00 -0.3 33674196 53
4: 2019-03-04 00:00:00 0.6 43566324 64
5: 2019-03-04 00:00:00 -0.5 74949678 66
6: 2019-03-04 00:00:00 -0.4 35799917 58
我什至不知道从哪里开始,似乎我无法使用任何现有的图表类型甚至组合。堆叠的条形图无法正常工作,因为每个条形图的宽度都需要根据数量/数量进行调整。我当时在考虑使用人口金字塔,但是我不确定是否可以使用正确的x轴(日期),而且左栏几乎是不可见的,因为右栏具有更大的值并且共享相同的轴。
有人知道如何在r中绘制此图表吗?最好使用plotly或ggplot2。
更新: 我的数据包含几个日期,因此图表实际上应该像这样
这是新的数据示例
date,level,volume,count
2019-03-04,0.4,50193087,51
2019-03-04,0.1,30030902,50
2019-03-04,-0.3,33674196,53
2019-03-04,0.6,43566324,64
2019-03-04,-0.5,74949678,66
2019-03-04,-0.4,35799917,58
2019-03-04,-0.1,99431328,46
2019-03-05,0.8,85373468,45
2019-03-05,0.5,76080717,51
2019-03-05,-0.7,45250685,48
2019-03-05,-0.9,47862662,48
2019-03-05,-0.2,43731758,48
2019-03-05,0.3,43375430,45
答案 0 :(得分:1)
好吧,尽管我不确定,这将是我对所问问题的最佳猜测。
首先,我阅读了您的数据,发布者可能会跳过这些数据,但可能会帮助其他人复制它:
zz <- "date,time,level,volume,count
2019-03-04,00:00:00,0.4,50193087,51
2019-03-04,00:00:00,0.1,30030902,50
2019-03-04,00:00:00,-0.3,33674196,53
2019-03-04,00:00:00,0.6,43566324,64
2019-03-04,00:00:00,-0.5,74949678,66
2019-03-04,00:00:00,-0.4,35799917,58"
df <- read.table(header = T, text = zz, sep = ",")
然后,我将您的数据复制到两个单独的data.frames
中,并给每个其他方面变量:
df1 <- df
df1$facet <- factor("count", levels = c("volume","count"))
df2 <- df
df2$facet <- factor("volume", levels = c("volume","count"))
然后我们建立情节:
ggplot(df1, aes(y = as.factor(level))) +
# We have to call geom_tile twice since we work with two data.frames, y is inherited
geom_tile(data = df1,
aes(x = 0.5 * count, width = count, height = 0.6, fill = level > 0)) +
# The trick is to map the volume to negative values
geom_tile(data = df2,
aes(x = -0.5 * volume, width = volume, height = 0.6, fill = level > 0)) +
# Then we give some colours to the bars
scale_fill_manual(values = c("TRUE" = "limegreen", "FALSE" = "red")) +
# Now we make sure the labelling is sensible on the x-axis, date is given as axis title.
scale_x_continuous(expand = c(0, 0, 0, 0),
labels = function(x){ifelse(x < -1e6, paste0(abs(x)/1e6, "M"), x)},
name = df1$date[1]) +
scale_y_discrete(name = "level") +
# Now we're making facets out of count/volume en set 'scales = "free_x"'
# to let them scale independently
facet_grid(~ facet, scales = "free_x", switch = "x") +
# Add a fake y-axis
geom_vline(xintercept = 0) +
# Fiddle around with themes
# strip.placement and 'switch = "x"' above let volume/count labels take place of x-axis
# Panel spacing is set to zero to let the facets appear as if it were one
theme_minimal() +
theme(strip.placement = "outside",
panel.spacing.x = unit(0, "mm"),
axis.line.x = element_line(colour = "black"))
结果:
是在您想念的地方吗?
编辑:x轴上多个日期(某种)的解决方案。首先,我重构数据以在那里获取更多日期:
# df from previous example
df <- reshape2::melt(df, id.vars = c("date","level", "time"))
df2 <- cbind(date = "2019-03-05", df[,-1])
df3 <- cbind(date = "2019-03-06", df[,-1])
df <- rbind(df, df2, df3)
接下来,它将看起来很像以前的图,并添加了geom_blank()
,可确保每个体积/数量具有相同的x轴范围,并将日期用作构面变量。
ggplot(df) +
geom_tile(data = df[df$variable == "count",],
aes(y = as.factor(level), x = 0.5 * value, width = value, fill = level > 0),
height = 2/(1 + sqrt(5))) +
geom_tile(data = df[df$variable == "volume",],
aes(y = as.factor(level), x = -0.5 * value, width = value, fill = level > 0),
height = 2/(1 + sqrt(5))) +
# This controls x scale range to get uniform x-axis between dates
geom_blank(data = data.frame(x = c(-max(df$value[df$variable == "volume"]),
max(df$value[df$variable == "count"])),
y = 0, variable = c("volume", "count")),
aes(x = x * 1.1, y = y)) +
geom_vline(xintercept = 0) +
# Drop the name
scale_x_continuous(expand = c(0,0,0,0),
labels = function(x){abs(x)},
name = "") +
# Now facet over data and variable
facet_grid(~ date + variable, switch = "x", scales = "free_x") +
theme_minimal() +
theme(strip.placement = "outside",
# You can also set all spacing to unit(0,"mm") for a continuous look.
panel.spacing.x = unit(rep_len(c(0, 5.5), 2*nlevels(df$date) - 1), "pt"),
axis.line.x = element_line(colour = "black"))
看起来像这样:
您会注意到日期的位置不是特别合适,我们无法使用变量在代码中切换日期,否则它将按计数/数量而不是日期进行分组。也没有简单的方法来删除日期重复。以我的辩护,将3个非常不同的变量映射到同一根轴可能有点过大。但是,如果您确实希望日期标签看起来很漂亮,建议您看一下这个问题:Nested facets in ggplot2 spanning groups,或者使用图像编辑程序在R之外对其进行编辑。