2017-07-05 10 views
0

ggplotを使って、週表示のカレンダー/タイムテーブル/タイムシート/滝をプロットしたいと思います。次のようにサンプルデータは、(sampleData.csv)になります。ggplot:スタックされたバーを手動で各Xで別々にソートする方法は?

date, start, end, duration, name, color 
2016-08-04, 00:00:00, 08:00:00, 8.00, idle, #00000000 
2016-08-04, 08:00:00, 10:00:00, 2.00, Coding, red 
2016-08-04, 10:00:00, 14:00:00, 4.00, idle, #00000000 
2016-08-04, 14:00:00, 17:30:00, 3.50, Laundry, green 
2016-08-04, 17:30:00, 20:00:00, 2.50, Cooking, blue 
2016-08-04, 20:00:00, 24:00:00, 4.00, idle, #00000000 
2016-08-05, 00:00:00, 06:00:00, 6.00, idle, #00000000 
2016-08-05, 06:00:00, 09:00:00, 3.00, Cooking, blue 
2016-08-05, 09:00:00, 10:00:00, 1.00, Laundry, green 
2016-08-05, 10:00:00, 12:30:00, 2.50, idle, #00000000 
2016-08-05, 12:30:00, 16:00:00, 3.50, Coding, red 
2016-08-05, 16:00:00, 22:00:00, 6.00, Basketball, brown 
2016-08-05, 22:00:00, 24:00:00, 2.00, idle, #00000000 

現在、私はこのようにそれらをプロットすることができる午前:

    Correctly ordered but no legend, plus ugly colors.

    しかし、2つの欠点があります

  1. 私はは伝説を作ることができませんこれらのバーをグループ化します。
  2. には、行ごとにを指定する必要がありました。このスタイルをデータにハードコードするのは本当に面倒です。

凡例を有効にし、着色ジョブをggplotに残すには、aes(fill=name)コマンドを使用しました。しかし、私のスケジュールを台無しに彼らの「名前」の値に応じて各日付で自動的にソートバーをggplot:

With legend but ill-ordered.

というサンプルデータに注意してください:私がしたい

  • "color"列を取り除き、ggplotが各nameに自動的に色を割り当てるようにします。
  • 各日付で「期間」の合計は24(時間)です。これは今私が特定のYに棒を置く方法です。 X軸の上にあるバーを "浮動させる"方法については、私は開いています。
  • 各日付に、同じ「名前」フィールドを持つ複数のエントリが存在することがあります。たとえば、「アイドル」エントリは00:00、10:00、および20:00に開始します。これが、「名前」フィールドによって自動的にソートされないようにする理由の1つです。
  • 異なる日付間では、異なる「名前」のエントリの順序が変更される可能性があります。これは、自動的にソートされない別の理由です。別の方法で私の質問を状態に

    library(readr) 
    data <- read_csv("sampleData.csv", 
           col_types = cols(date = col_date(format = "%Y-%m-%d"), 
                end = col_time(format = "%H:%M:%S"), 
                start = col_time(format = "%H:%M:%S"))) 
    library(ggplot2) 
    # The first way to plot it: 
    ggplot(data, aes(x = date, y = duration, fill=name)) + 
        geom_bar(stat = "identity") + 
        scale_y_reverse(breaks=0:24)+#function(x) seconds_to_period(x))#strftime(chron(times=c(x/86400)), "%H:%M"))#+coord_flip() 
        coord_cartesian(ylim = c(0, 24), expand = FALSE)+ 
        labs(x = "Date", y = "Time (Hour)", 
         title = "Timetable", 
         subtitle = "using aes(fill=name)", 
         caption = "Legend is plotted and colors are well chosen, but bars at each date are sorted by \"name\" (unwanted).")+ 
        scale_x_date(date_breaks = "2 month", date_labels = "%b %Y") 
    # The second way to plot it: 
    ggplot(data, aes(x = date, y = duration)) + 
        geom_bar(stat = "identity", fill = data$color) + 
        scale_y_reverse(breaks=0:24)+#function(x) seconds_to_period(x))#strftime(chron(times=c(x/86400)), "%H:%M"))#+coord_flip() 
        coord_cartesian(ylim = c(0, 24), expand = FALSE)+ 
        labs(x = "Date", y = "Time (Hour)", 
         title = "Timetable", 
         subtitle = "using geom_bar(fill=data$color)", 
         caption = "Bars at each date are correctly positioned, but legend is not available.")+ 
        scale_x_date(date_breaks = "2 month", date_labels = "%b %Y") 
    

    :ここ

は、上記の二つのプロットを生成するコードがどのように私は伝説と時刻表を作ることができますか?

答えて

1

geom_rect()geom_bar()よりも、この場合により良い選択である:

library(ggplot2) 
ggplot(df) + 
    geom_rect(aes(xmin = date, xmax = date + .8, 
        ymin = start, ymax = end, 
        fill = name), 
       color = 'black') + 
    scale_y_datetime(date_labels = "%H:%M") + 
    scale_x_date(date_breaks = "2 months", date_labels = "%b %Y") + 
    labs(x = "Date", 
     y = "Time (Hour)", 
      title = "Timetable" 
     ) 

データ:

df <- read.table(text = 'date, start, end, duration, name, color 
       2016-08-04, 00:00:00, 08:00:00, 8.00, idle, #00000000 
       2016-08-04, 08:00:00, 10:00:00, 2.00, Coding, red 
       2016-08-04, 10:00:00, 14:00:00, 4.00, idle, #00000000 
       2016-08-04, 14:00:00, 17:30:00, 3.50, Laundry, green 
       2016-08-04, 17:30:00, 20:00:00, 2.50, Cooking, blue 
       2016-08-04, 20:00:00, 24:00:00, 4.00, idle, #00000000 
       2016-08-05, 00:00:00, 06:00:00, 6.00, idle, #00000000 
       2016-08-05, 06:00:00, 09:00:00, 3.00, Cooking, blue 
       2016-08-05, 09:00:00, 10:00:00, 1.00, Laundry, green 
       2016-08-05, 10:00:00, 12:30:00, 2.50, idle, #00000000 
       2016-08-05, 12:30:00, 16:00:00, 3.50, Coding, red 
       2016-08-05, 16:00:00, 22:00:00, 6.00, Basketball, brown 
       2016-08-05, 22:00:00, 24:00:00, 2.00, idle, #00000000', header = TRUE, sep = ',') 
df$date <- as.Date(df$date) 
df$start <- as.POSIXct(df$start, format = "%H:%M:%S") 
df$end <- as.POSIXct(df$end, format = "%H:%M:%S") 
+0

はありがとうございます。これは非常にエレガントなソリューションです!しかし、ここで 'scale_y_datetime'の使い方は私のY軸を反転させました。毎週のカレンダーのように、Y軸が上下に大きくなることがあります。誰かが必要な場合に備えて、で可能な修正があります。 – tslmy

関連する問題