Як вертикально скласти два графіки з однаковою шкалою x, але різною шкалою y в R?


9

Привітання,

В даний час я роблю наступне в R:

require(zoo)
data <- read.csv(file="summary.csv",sep=",",head=TRUE)
cum  = zoo(data$dcomp, as.Date(data$date))
data = zoo(data$compressed, as.Date(data$date))
data <- aggregate(data, identity, tail, 1)
cum  <- aggregate(cum, identity, sum, 1)
days = seq(start(data), end(data), "day")
data2 = na.locf(merge(data, zoo(,days)))

plot(data2,xlab='',ylab='compressed bytes',col=rgb(0.18,0.34,0.55))
lines(cum,type="h",col=rgb(0,0.5,0))

Фрагмент резюме.csv:

date,revision,file,lines,nclass,nattr,nrel,bytes,compressed,diff,dcomp
2007-07-25,16,model.xml,96,11,22,5,4035,991,0,0
2007-07-27,17,model.xml,115,16,26,6,4740,1056,53,777
2007-08-09,18,model.xml,106,16,26,7,4966,1136,47,761
2007-08-10,19,model.xml,106,16,26,7,4968,1150,4,202
2007-09-06,81,model.xml,111,16,26,7,5110,1167,13,258
...

Останні два рядки описують потрібну мені інформацію, і результат нагадує наступне: alt текст Синя лінія - це ентропія в байтах артефакту, який мене цікавить. Зелені лінії відображають ентропію змін.

Тепер у цьому графіку він працює добре, оскільки масштабів немає великої різниці. Але в мене є інші графіки, де зелені лінії стають такими маленькими, що їх неможливо побачити.

Я шукав рішення, включаючи дві речі:

  1. Щоб перемістити зелені вертикальні лінії до другого графіка, трохи нижче першого, із власною віссю y, але розділеною осі x.
  2. Щоб надати йому логарифмічну шкалу, оскільки мене більше цікавить "величина", ніж конкретні значення.

Спасибі заздалегідь!

PS Якщо хтось також може сказати мені, як я міг би поставити "незначні кліщі" у шкалі x, що стосуються місяців, я вдячний :-) Якщо це занадто багато питань для однієї посади, я можу поділити їх далі.

Відповіді:


15

Ви можете використовувати par(new=TRUE)для побудови на одному графіку за допомогою двох різних осей y! Це також повинно вирішити вашу проблему.

Далі ви знайдете простий приклад, який побудує дві випадкові нормальні змінні, одна на середній 0, а інша на середній 100 (обидва sd s = 1) в одному графіку. Перший червоним кольором на лівій осі y, другий синім кольором на правій осі у. Потім додаються мітки осі.

Ось вам:

x <- 1:10
y1 <- rnorm(10)
y2 <- rnorm(10)+100

plot(x,y1,pch=0,type="b",col="red",yaxt="n",ylim=c(-8,2))
par(new=TRUE)
plot(x,y2,pch=1,type="b",col="blue",yaxt="n",ylim=c(98,105))

axis(side=2)
axis(side=4)

виглядає ось так (згадайте червоний на лівій осі, синій на правій осі): alt текст

ОНОВЛЕННЯ:
На основі коментарів я створив оновлену версію свого графіка. Тепер я трохи більше заглиблююсь у функціональність базового графіка, використовуючи par(mar=c(a,b,c,d))для створення більшого поля навколо графіка (необхідного для правої мітки осі), mtextдля показу міток осі та розширеного використання axisфункції:

x <- 1:100
y1 <- rnorm(100)
y2 <- rnorm(100)+100

par(mar=c(5,5,5,5))

plot(x,y1,pch=0,type="b",col="red",yaxt="n",ylim=c(-8,2),ylab="")
axis(side=2, at=c(-2,0,2))
mtext("red line", side = 2, line=2.5, at=0)

par(new=TRUE)
plot(x,y2,pch=1,type="b",col="blue",yaxt="n",ylim=c(98,108), ylab="")
axis(side=4, at=c(98,100,102), labels=c("98%","100%","102%"))
mtext("blue line", side=4, line=2.5, at=100)

alt текст

Як бачите, це досить прямо вперед. Ви можете визначити позицію своїх даних ylimу plotфункції, а потім atза допомогою axisфункції вибрати, яку клітинку осі ви хочете бачити. Крім того, ви можете навіть надати мітки для осі кліщів (досить корисно для номінальної осі x) за labelsдопомогою axisфункції (зроблено тут на правій осі). Щоб додати мітки осей, використовувати mtextз atдля вертикального позиціонування ( lineдля горизонтального позиціонування).

Переконайтеся в тому , щоб перевірити ?plot, ?par, ?axisі ?mtextдля отримання додаткової інформації.
Великими веб-ресурсами є: Швидкий R для графіків: 1 , 2 та 3 .


Це цікаво, але як ми можемо сказати читачеві, яка шкала відповідає якому рядку?
Уго Серено Феррейра

Подивіться на цей графік: imgur.com/K8BCr.png Там ми представляємо мітки та галочки осі y лише там, де вони застосовуються до даних (тобто для лівої осі у верхній частині графіка, як відповідних даних, а для правої осі в нижній частині графіка, як відповідні дані). Крім того, ми використовували різні кольори (як у прикладі вище) та типи рядків та пояснювали це у підписі. Ви також можете використовувати лінійну діаграму зліва та смугову діаграму на правій осі, щоб зробити чіткіше чіткіше.
Генрік

Наведений вами приклад дуже хороший ... Як вам вдалося вертикально змістити кожну вісь?
Уго Серено Феррейра

2
Дійсно хороший приклад. Єдине питання вашого графіка - це те, що обидва імена змінних Y перетинаються. У цьому випадку ви хочете, щоб один зліва, а другий праворуч (можливо, навіть у вертикальному положенні). Щоб модернізувати свій приклад з "дійсно добре" до "ідеального", ви можете скористатися функцією mtext з R, щоб зробити імена змінних
Дейв Келлен

@Hugo @Dave: Перегляньте моє оновлення щодо включення обох коментарів.
Генрік

12

Я думаю, ви можете отримати те, що хочете, використовуючи ggplot2. Використовуючи наведений нижче код, я можу створити:

alt текст

Очевидно, що такі речі, як кольори ліній, можна змінити на все, що завгодно. На осі x я вказав основні лінії по роках і другорядні лінії по місяцях.

require(ggplot2)
t = as.Date(0:1000, origin="2008-01-01")  
y1 = rexp(1001)
y2 = cumsum(y1)
df = data.frame(t=t, values=c(y2,y1), type=rep(c("Bytes", "Changes"), each=1001))

g = ggplot(data=df, aes(x=t, y=values)) +
  geom_line() +
  facet_grid(type ~ ., scales="free") +
  scale_y_continuous(trans="log10") +
  scale_x_date(major="years", minor="months") +
  ylab("Log values")
g

Так, я спробував налаштувати df = data.frame (t = дні, значення = c (data2, cum), type = rep (c ("Байти", "Зміни"), кожен = 1001)), але це дає Помилка rbind.zoo (...): індекси перекриваються
Уго Серено Феррейра

Це тому, що data2 та cum - об’єкти зоопарку. Використовуйте as.vector (data2), щоб отримати неотримані значення. Також я використовував 1001, тому що у мене було 1001 спостереження. Вам знадобиться щось інше.
csgillespie

Користувач Noob R тут: помилка в data.frame (t = дні, значення = c (as.vector (data2), as.vector (cum)),: аргументи передбачають різну кількість рядків: 1063, 1300, 2
Hugo Sereno Феррейра

Введіть "дні", "data2" та "cum", щоб переглянути свої дані. Потім подивіться на "тривалість (дні)" і т. Д. Вам потрібно зіставити часові точки зі значеннями.
csgillespie
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.