【问题标题】:Draw market chart bar using R使用R绘制市场图表条
【发布时间】:2019-09-16 23:06:35
【问题描述】:

我需要在 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

【问题讨论】:

  • 我是否理解正确,您希望在 x 轴上显示日期,在 x 轴上也需要音量/计数(通过条形宽度)?我非常有信心您可以将音量和计数映射到 x 轴,但不能映射到日期。

标签: r ggplot2 plotly financial


【解决方案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 之外编辑它们。

【讨论】:

  • 是的,它看起来和我想要的完全一样。非常感谢。但是,我发现您的解决方案存在一个问题。您假设只有一个日期,但有一系列日期。很抱歉,我没有在描述中澄清这一点。我更新了描述中的示例。我想我需要用日期绘制第二个 x 轴。或者也许还有其他解决方案。
猜你喜欢
  • 1970-01-01
  • 2015-07-13
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 2020-02-09
  • 1970-01-01
  • 1970-01-01
  • 2021-06-24
相关资源
最近更新 更多