2017-01-04 62 views
2

ための目盛り間の均一な距離私はこの古温度R.の図の基本的な温度の傾向を再作成しようとしていますRプロット:(。<a href="https://commons.wikimedia.org/wiki/File:All_palaeotemps.svg" rel="nofollow noreferrer">Original image</a>と<a href="http://gergs.net/?attachment_id=4310" rel="nofollow noreferrer">data</a>)非一様番号

enter image description here

の目盛間隔x軸は数百万年から100万〜数百万に、そして100万に変化しますが、ティックマークは均等に配置されています。元の図形は、スペーシングを達成するためにExcelで5つの別々のグラフに注意深くレイアウトされています。 Rで同じx軸レイアウトを取得しようとしています。

私は2つの基本的なアプローチを試みました。最初のアプローチは、par(fig=c(x1,x2,y1,y2))を使用して5つの別々のグラフを並べて配置することでした。問題は、目盛りの間隔が一定でなく、ラベルが重なり合うことです。

#1 
par(fig=c(0,0.2,0,0.5), mar=c(3,4,0,0)) 
plot(paleo1$T ~ paleo1$Years, col='red3', xlim=c(540,60), bty='l',type='l', ylim=c(-6,15), ylab='Temperature Anomaly (°C)') 
abline(0,0,col='gray') 

#2 
par(fig=c(0.185,0.4,0,0.5), mar=c(3,0,0,0), new=TRUE) 
plot(paleo2$T ~ paleo2$Year, col='forestgreen', axes=F, type='l', xlim=c(60,5), ylab='', ylim=c(-6,15)) 
axis(1, xlim=c(60,5)) 
abline(0,0,col='gray') 

#etc. 

enter image description here

第二のアプローチ(および私の好ましいアプローチ、可能な場合)は、単一のグラフにデータをプロットすることです。これはティックマークが「自然な」順序に従うため、ティックマーク間の距離が不均一になります。 (編集:サンプルデータとフルデータセットへのリンクが追加されました)。

years <- c(500,400,300,200,100,60,50,40,30,20,10,5,4,3,2,1) 
temps <- c(13.66, 8.6, -2.16, 3.94, 8.44, 5.28, 12.98, 8.6, 5, 5.34, 3.66, 2.65, 0.78, 0.25, -1.51, -1.77) 
test <- data.frame(years, temps) 
names(test) <- c('Year','T') 

# The full csv file can be used with this line instead of the above. 
# test <- read.csv('https://www.dropbox.com/s/u0dfmlvzk0ztpkv/paleo_test.csv?dl=1') 

plot(test$T ~ test$Year, type='l', xaxt='n', xlim=c(520,1), bty='l', ylim=c(-5,15), xlab="", ylab='Temperature Anomaly (°C)') 
ticklabels = c(500,400,300,200,100,60,50,40,30,20,10,5,4,3,2,1) 
axis(1, at=ticklabels) 

enter image description here

plotlog='x'を追加する最も近いが、ダニの間隔はまださえではなく、実際のスケールは、当然のことながら、対数目盛ではありません。私は最初の問題を解決しようとしていますが、私の目標は、上記のオリジナルフィギュアを一致させることですので、私の例はわずか1万年に下る

enter image description here

。私はggplotのソリューションを公開していますが、私はそれに慣れ親しんでいます。ここで

+0

興味深い質問を。あなたはその質問にいくつかのサンプルデータを提供できますか?参照:[素晴らしいRの再現可能な例を作る方法](http://stackoverflow.com/questions/5963269) – Axeman

+1

"時間尺度"あたり5~10のデータポイント/パネルで十分でしょう。もっともっと8MBのデータへのリンクよりも魅力的です... – Henrik

+3

私は実際に(そのサーバーはsloooowです)データをダウンロードする手間に行きました。私が[整理されたデータ](http://vita.had.co.nz/papers/tidy-data.pdf)とはみなされず、多くのクリーンアップと再編成が必要であることを発見したときの私の喜びを想像してみてください。使用可能な形式でデータを共有してください。 – Roland

答えて

3

私は言って別のノートを打つます:ありません。私の経験では、ggplot2(およびそれよりも少ない程度に、ベースグラフィックス)で行うことがより困難なものは、良い考えである可能性は低くなります。ここで問題となるのは、スケールを一貫して変更することは、視聴者を迷惑にさせる可能性が高いことです。

代わりに、ログスケールを使用し、手動でカットオフを設定することをお勧めします。

まず、ここだけ、あなたの質問のフルスケールそうカバーするために、いくつかの長いデータである。そして、

longerTest <- 
    data.frame(
    Year = rep(1:9, times = 6) * rep(10^(3:8), each = 9) 
    , T = rnorm(6*9)) 

を、私はプロット内でラベルを配置するために、いくつかのカットオフを選びました。これらはあなたが好きなように調整が、少なくとも合理的に間隔を置いたダニのための出発点ですることができます。

forLabels <- 
    rep(c(1,2,5), times = 6) * rep(10^(3:8), each = 3) 

その後、私は手動でラベルに追加するいくつかのことを設定します。したがって、軸の一部の下で「何千年も」言う必要はなく、単に「k」でラベル付けすることができます。それぞれの大きさのオーダーは値を取得します。名前は物事をまっすぐに保つのに役立つだけであることを注記しておきます。したがって、最初の2つをスキップした場合は、下のインデックスを調整する必要があります。

toAppend <- 
    c("1" = "0" 
    , "2" = "00" 
    , "3" = "k" 
    , "4" = "0k" 
    , "5" = "00k" 
    , "6" = "M" 
    , "7" = "0M" 
    , "8" = "00M") 

その後、私は私が最初の桁をつかむと、上から正しいサフィックスを連結して使用するテキストのバージョンに私のforLabelsを変更します。

[1] "1k" "2k" "5k" "10k" "20k" "50k" "100k" "200k" "500k" "1M" "2M" 
[12] "5M" "10M" "20M" "50M" "100M" "200M" "500M" 

あなたはおそらく、これらは基本グラフィックスのために使用することができますが、あなたがやりたい対数スケールを取得することは、時にはトリッキーです:

myLabels <- 
    paste0(
    substr(as.character(forLabels), 1, 1) 
    , toAppend[floor(log10(forLabels))] 
) 

これができます。代わりに、あなたはggplot2ソリューションに開かれていると述べたことから、私は大きなから小型まで実行ログスケール取得するthis answerからこの修正対数目盛をつかん:ちょうどデータを渡し、その後

library("scales") 
reverselog_trans <- function(base = exp(1)) { 
    trans <- function(x) -log(x, base) 
    inv <- function(x) base^(-x) 
    trans_new(paste0("reverselog-", format(base)), trans, inv, 
      log_breaks(base = base), 
      domain = c(1e-100, Inf)) 
} 

を、および設定します希望休憩と規模:

ggplot(longerTest 
     , aes(x = Year 
      , y = T)) + 
    geom_line() + 
    scale_x_continuous(
    breaks = forLabels 
    , labels = myLabels 
    , trans=reverselog_trans(10) 
) 

は与える:consistenを持って

enter image description here

をより均一に標識される。

あなたは色をしたい場合は、cutを使用していることを行うことができます。

ggplot(longerTest 
     , aes(x = Year 
      , y = T 
      , col = cut(log10(Year) 
         , breaks = c(3,6,9) 
         , labels = c("Thousands", "Millions") 
         , include.lowest = TRUE) 
      , group = 1 
      )) + 
    geom_line() + 
    scale_x_continuous(
    breaks = forLabels 
    , labels = myLabels 
    , trans=reverselog_trans(10) 
) + 
    scale_color_brewer(palette = "Set1" 
        , name = "How long ago?") 

enter image description here

をここでは異なるスケールを作成するfacet_wrapを使用したバージョンです。私はここで6を使いましたが、代わりにどんなしきい値を設定することもできます。

longerTest$Period <- 
    cut(log10(longerTest$Year) 
     , breaks = c(3, 4, 5, 6, 7, 8, 9) 
     , labels = paste(rep(c("", "Ten", "Hundred"), times = 2) 
         , rep(c("Thousands", "Millions"), each = 3)) 
     , include.lowest = TRUE) 

longerTest$Period <- 
    factor(longerTest$Period 
     , levels = rev(levels(longerTest$Period))) 


newBreaks <- 
    rep(c(2,4,6,8, 10), times = 6) * rep(10^(3:8), each = 5) 

newLabels <- 
    paste0(
    substr(as.character(newBreaks), 1, 1) 
    , toAppend[floor(log10(newBreaks))] 
) 

ggplot(longerTest 
     , aes(x = Year 
      , y = T 
     )) + 
    geom_line() + 
    facet_wrap(~Period, scales = "free_x") + 
    scale_x_reverse(
    breaks = newBreaks 
    , labels = newLabels 
) 

います:

enter image description here

+0

ありがとうございます。理性的な根底にある私の姿のために、上記の@Henrikへの私のコメントを見てください。生徒はスケールの文脈を持つでしょう。 –

+1

この場合、私はそれが(間違いなく)間違ったデータの視覚化の実践を教えていると主張します。このようなログスケールを使用すると、大規模なデータ範囲(ログスケール)や複雑な視覚化のためのExcelの制限をどのように見えるかを示すための良い移行方法となります。別のスケールで絶対に行う必要がある場合は、 'facet_wrap'アプローチ(たぶん手動でブレーク/ラベルを設定することと組み合わせる)は、プロットを少しずつ分離するための正しい方法です。 –

+0

私はあなたの議論の視覚化に完全に同意しますが、これは視覚化の練習ではありません。それは気候変動運動です。その目的は、地球の気温が時間とともに大きく変動していることを示すことです。練習の別の部分では、現在の変化率*が過去の予想速度よりも速いことがわかります。 –

2

がスタートです:

#define the panels 
breaks <- c(-Inf, 8, 80, Inf) 
test$panel <- cut(test$Year, breaks, labels = FALSE) 
test$panel <- ordered(test$panel, levels = unique(test$panel)) 

#for correct scales 
dummydat <- data.frame(Year = c(0, 8, 8, 80, 80, max(test$Year)), 
         T = mean(test$T), 
         panel = ordered(rep(1:3, each = 2), levels = levels(test$panel))) 

library(ggplot2) 
ggplot(test, aes(x = Year, y = T, color = panel)) + 
    geom_line() + 
    geom_blank(data = dummydat) + #for correct scales 
    facet_wrap(~ panel, nrow = 1, scales = "free_x") + 
    theme_minimal() + #choose a theme you like 
    theme(legend.position = "none", #and customize it 
     panel.spacing.x = unit(0, "cm"), 
     strip.text = element_blank() , 
     strip.background = element_blank()) + 
    scale_x_reverse(expand = c(0, 0)) 

resulting plot

1

ここgridExtraを使用して、別のプロットでそれを行うための基本的な例です。例えば、エポックボックスを上端に作成する場合(ここでは行われません)など、余分なものと組み合わせると便利です(grobs)。必要に応じて、これはRolandのソリューションと組み合わせるのが最も良いかもしれません。

# ggplot with gridExtra 
library('ggplot2') 
library('gridExtra') 
library('grid') 

d1 <- test[1:5, ] 
d2 <- test[6:11, ] 
d3 <- test[12:16, ] 

plot1 <- ggplot(d1, aes(y = T, x = seq(1:nrow(d1)))) + 
    geom_line() + 
    ylim(c(-5, 15)) + 
    theme_minimal() + 
    theme(axis.title.x = element_blank(), 
     plot.margin = unit(c(1,0,1,1), "cm")) + 
    scale_x_continuous(breaks=) 

plot2 <- ggplot(d2, aes(y = T, x = seq(1:nrow(d2)))) + 
    geom_line() + 
    ylim(c(-5, 15)) + 
    theme_minimal() + 
    theme(axis.text.y = element_blank(), 
     axis.title.y = element_blank(), 
     axis.ticks.y = element_blank(), 
     axis.title.x = element_blank(), 
     plot.margin = unit(c(1,0,1,0), "cm")) 

plot3 <- ggplot(d3, aes(y = T, x = seq(1:nrow(d3)))) + 
    geom_line() + 
    theme_minimal() + 
    theme(axis.text.y = element_blank(), 
     axis.title.y = element_blank(), 
     axis.ticks.y = element_blank(), 
     axis.title.x = element_blank(), 
     plot.margin = unit(c(1,0,1,0), "cm")) + 
    ylim(c(-5, 15)) 

# put together 
grid.arrange(plot1, plot2, plot3, nrow = 1, 
      widths = c(1.5,1,1)) # allow extra width for first plot which has y axis 

enter image description here

関連する問題