Вопрос

Я новичок в R/GGPLOT. Я хотел бы создать график GEOM_LINE непрерывного временного ряда переменной, а затем добавить слой, состоящий из событий. Непрерывная переменная и ее временные метки хранятся в одном данных.

Что бы я В самом деле нравится делать что -то вроде графиков на finance.google.com. В тех, временные ряды-это стоимость, и есть «флаги», чтобы указать новости о новостях. Я на самом деле не замышляю финансирование, но тип графика похож. Я пытаюсь построить визуализации данных файла журнала. Вот пример того, что я имею в виду ...

google chart with events

Если рекомендуется (?), Я хотел бы использовать отдельные данные. Фреймы для каждого уровня (один для непрерывных наблюдений переменных, другой для событий).

После некоторой проб и ошибок это примерно так близко, насколько я могу получить. Здесь я использую примеры данных из наборов данных, которые поставляются с GGPLOT. «Экономика» содержит некоторые данные временных рядов, которые я хотел бы построить, а «президента» содержит несколько событий (президентские выборы).

library(ggplot2)
data(presidential)
data(economics)

presidential <- presidential[-(1:3),]
yrng <- range(economics$unemploy)
ymin <- yrng[1]
ymax <- yrng[1] + 0.1*(yrng[2]-yrng[1])

p2 <- ggplot()
p2 <- p2 + geom_line(mapping=aes(x=date, y=unemploy), data=economics , size=3, alpha=0.5) 
p2 <- p2 + scale_x_date("time") +  scale_y_continuous(name="unemployed [1000's]")
p2 <- p2 + geom_segment(mapping=aes(x=start,y=ymin, xend=start, yend=ymax, colour=name), data=presidential, size=2, alpha=0.5)
p2 <- p2 + geom_point(mapping=aes(x=start,y=ymax, colour=name ), data=presidential, size=3) 
p2 <- p2 + geom_text(mapping=aes(x=start, y=ymax, label=name, angle=20, hjust=-0.1, vjust=0.1),size=6, data=presidential)
p2

my attempt

Вопросы:

  • Это нормально для очень редких событий, но если их есть кластер (как часто случается в файле журнала), это становится грязно. Есть ли какая -то техника, которую я могу использовать, чтобы аккуратно показать кучу событий, происходящих в короткий промежуток времени? Я думал о Position_jitter, но мне было очень трудно зайти так далеко. Google Charts складывает эти «флаги» на друг другу, если их много.

  • Я на самом деле не люблю придерживаться данных о событии в том же масштабе, что и непрерывный дисплей измерения. Я бы предпочел поместить его в facet_grid. Проблема в том, что все аспекты должны быть получены из тех же данных. Если так, это также кажется не идеальным (или, может быть, я просто пытаюсь избежать использования RESHAPE?)

Это было полезно?

Решение

Как бы мне ни нравился ответ @jd Long, я положу тот, который только в r/ggplot2.

Подход состоит в том, чтобы создать второй набор данных событий и использование его для определения позиций. Начиная с того, что было @Angelo:

library(ggplot2)
data(presidential)
data(economics)

Вытащите данные о событии (президентские) и преобразуйте их. Вычислять baseline а также offset как фракции экономических данных, с которыми он будет нанесен. Установите дно (ymin) к базовой линии. Здесь приходит сложная часть. Мы должны быть в состоянии ошеломлять этикетки, если они слишком близки друг к другу. Поэтому определите расстояние между соседними метками (предполагает, что события отсортированы). Если это меньше, чем какое -то количество (я выбрал около 4 лет для этой шкалы данных), обратите внимание, что эта метка должна быть выше. Но это должно быть выше, чем тот, который после него, поэтому используйте rle Чтобы получить длину TRUES (то есть должен быть выше) и вычислить вектор смещения, используя это (каждая строка из TRUE должен отсчитывать от его длины до 2, FALSES только в смещении 1). Используйте это, чтобы определить верхнюю часть стержней (ymax).

events <- presidential[-(1:3),]
baseline = min(economics$unemploy)
delta = 0.05 * diff(range(economics$unemploy))
events$ymin = baseline
events$timelapse = c(diff(events$start),Inf)
events$bump = events$timelapse < 4*370 # ~4 years
offsets <- rle(events$bump)
events$offset <- unlist(mapply(function(l,v) {if(v){(l:1)+1}else{rep(1,l)}}, l=offsets$lengths, v=offsets$values, USE.NAMES=FALSE))
events$ymax <- events$ymin + events$offset * delta

Собрать это в сюжет:

ggplot() +
    geom_line(mapping=aes(x=date, y=unemploy), data=economics , size=3, alpha=0.5) +
    geom_segment(data = events, mapping=aes(x=start, y=ymin, xend=start, yend=ymax)) +
    geom_point(data = events, mapping=aes(x=start,y=ymax), size=3) +
    geom_text(data = events, mapping=aes(x=start, y=ymax, label=name), hjust=-0.1, vjust=0.1, size=6) +
    scale_x_date("time") +  
    scale_y_continuous(name="unemployed \[1000's\]")

Вы могли бы фасать, но это сложно с разными масштабами. Другой подход - сочинение двух графиков. Существует некоторая дополнительная ворчание, которое необходимо сделать, чтобы убедиться, что участки имеют одинаковый рентгеновский диапазон, чтобы эти этикетки были подходящими на нижнем графике и устранить ось x на верхнем графике.

xrange = range(c(economics$date, events$start))

p1 <- ggplot(data=economics, mapping=aes(x=date, y=unemploy)) +
    geom_line(size=3, alpha=0.5) +
    scale_x_date("", limits=xrange) +  
    scale_y_continuous(name="unemployed [1000's]") +
    opts(axis.text.x = theme_blank(), axis.title.x = theme_blank())

ylims <- c(0, (max(events$offset)+1)*delta) + baseline
p2 <- ggplot(data = events, mapping=aes(x=start)) +
    geom_segment(mapping=aes(y=ymin, xend=start, yend=ymax)) +
    geom_point(mapping=aes(y=ymax), size=3) +
    geom_text(mapping=aes(y=ymax, label=name), hjust=-0.1, vjust=0.1, size=6) +
    scale_x_date("time", limits=xrange) +
    scale_y_continuous("", breaks=NA, limits=ylims)

#install.packages("ggExtra", repos="http://R-Forge.R-project.org")
library(ggExtra)

align.plots(p1, p2, heights=c(3,1))

Другие советы

Теперь мне нравится GGPLOT так же, как и следующий парень, но если вы хотите сделать диаграммы типа Finance Google, почему бы просто не сделать это с API Google Graphics?!? Тебе понравится это:

install.packages("googleVis")
library(googleVis)

dates <- seq(as.Date("2011/1/1"), as.Date("2011/12/31"), "days")
happiness <- rnorm(365)^ 2
happiness[333:365] <- happiness[333:365]  * 3 + 20
Title <- NA
Annotation <- NA
df <- data.frame(dates, happiness, Title, Annotation)
df$Title[333] <- "Discovers Google Viz"
df$Annotation[333] <- "Google Viz API interface by Markus Gesmann causes acute increases in happiness."

### Everything above here is just for making up data ### 
## from here down is the actual graphics bits        ###
AnnoTimeLine  <- gvisAnnotatedTimeLine(df, datevar="dates",
                                       numvar="happiness", 
                                       titlevar="Title", annotationvar="Annotation",
                                       options=list(displayAnnotations=TRUE,
                                                    legendPosition='newRow',
                                                    width=600, height=300)
                                       )
# Display chart
plot(AnnoTimeLine) 
# Create Google Gadget
cat(createGoogleGadget(AnnoTimeLine), file="annotimeline.xml")

И это создает эту фантастическую таблицу:

enter image description here

Plotly это простой способ сделать GGPLOTS интерактивными. Чтобы отобразить события, приступите их к факторам, которые могут отображаться как эстетика, как цвет.

Конечным результатом является сюжет, который вы можете перетащить курсор. Заговоры отображают данные, представляющие интерес:

enter image description here

Вот код для создания ggplot:

# load data    
data(presidential)
data(economics)

# events of interest
events <- presidential[-(1:3),]

# strip year from economics and events data frames
economics$year = as.numeric(format(economics$date, format = "%Y")) 

# use dplyr to summarise data by year
#install.packages("dplyr")
library(dplyr)
econonomics_mean <- economics %>% 
  group_by(year) %>% 
  summarise(mean_unemployment = mean(unemploy))

# add president terms to summarized data frame as a factor
president <- c(rep(NA,14), rep("Reagan", 8), rep("Bush", 4), rep("Clinton", 8), rep("Bush", 8), rep("Obama", 7))
econonomics_mean$president <- president

# create ggplot
p <- ggplot(data = econonomics_mean, aes(x = year, y = mean_unemployment)) +
  geom_point(aes(color = president)) +
  geom_line(alpha = 1/3)

Требуется только одна строка кода, чтобы превратить ggplot в объект Plotly.

# make it interactive!
#install.packages("plotly")
library(plotly)
ggplotly(p)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top