Нарисуйте гистограмму с помощью R - PullRequest
0 голосов
/ 27 апреля 2019

Мне нужно нарисовать график профиля рынка (он же объем профиля) в R.

volume chart example

Выше приведен пример того, что я хочу.Горизонтальная ось - дата.На вертикальной оси у меня уровень.И мне также нужно иметь горизонтальную полосу на каждой дате и на каждом уровне, которая показывает объем (полоса справа) и счетчик (полоса слева).

Мои данные выглядят так.У меня есть столбцы с датой и уровнем, которые я хочу использовать для групп и тома, и считаю их значениями в качестве значений.

   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

Я даже не знаю, с чего начать, кажется, что могуt любые существующие типы диаграмм и даже комбинации.График с накоплением не будет работать, потому что ширина каждого бара должна быть скорректирована в соответствии с объемом / счетчиком.Я думал об использовании пирамиды населения, но я не уверен, что смогу использовать правильную ось х (дату), а левая полоса будет почти невидимой, потому что правая полоса имеет гораздо большие значения и имеет ту же ось.

Кто-нибудь знает, как я могу нарисовать этот график в г?Предпочтительно с помощью plotly или ggplot2.

ОБНОВЛЕНИЕ : Мои данные содержат несколько дат, поэтому диаграмма на самом деле должна выглядеть следующим образом

example with multiple dates

И здесьэто новый образец данных

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

1 Ответ

1 голос
/ 28 апреля 2019

Хорошо, это будет мое лучшее предположение о том, что спрашивают, хотя я не совсем уверен.

Сначала я читаю в ваших данных, которые постер может пропустить, но может помочь другим воспроизвести это.:

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"))

И результат:

enter image description here

Это где-то близко к тому, что вы имели в виду?

РЕДАКТИРОВАТЬ: решение для несколькихдаты (вроде) на оси х.Сначала я произвел рефакторинг данных, чтобы получить больше дат:

# 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"))

Что выглядит следующим образом:

enter image description here

Вы будетеобратите внимание, что даты не особенно удачно расположены, и мы не можем поменять их в нашем коде с помощью переменной, иначе она будет сгруппирована по количеству / объему, а не по дате.Также нет простого способа лишить дубликаты дат.В мою защиту, отображение 3 совершенно разных переменных на одной оси немного излишне.Но, если вы действительно хотите, чтобы метки даты выглядели красиво, я предлагаю вам взглянуть на этот вопрос: Вложенные фасеты в охватывающих группах ggplot2 или отредактируйте их вне R с помощью программы редактирования изображений.

...