R 數(shù)據(jù)可視化 —— ggplot 圖例設(shè)置

前言

坐標(biāo)軸和圖例被統(tǒng)稱為 guides,通常使用標(biāo)度函數(shù)來(lái)控制秋冰,如 limits, breaks 和 labels 參數(shù)。

坐標(biāo)軸與圖例很類似齐蔽,例如,坐標(biāo)軸的軸標(biāo)簽與圖例的標(biāo)題都是對(duì)應(yīng)到標(biāo)度函數(shù)的 name 參數(shù)床估,而圖例的標(biāo)識(shí)(key label)和軸的刻度標(biāo)簽對(duì)應(yīng)于標(biāo)度函數(shù)的 break 參數(shù)

除了可以在每個(gè)標(biāo)度函數(shù)中分開設(shè)置含滴,也可以使用 guides() 函數(shù)來(lái)進(jìn)行統(tǒng)一設(shè)置,兩種設(shè)置方式是等價(jià)的丐巫。

例如谈况,下面的設(shè)置方式是等價(jià)的

dat <- data.frame(x = 1:5, y = 1:5, p = 1:5, q = factor(1:5),
                  r = factor(1:5))
p <- ggplot(dat, aes(x, y, colour = p, size = q, shape = r)) + geom_point()

p1 <- p + guides(colour = "colorbar", size = "legend", shape = "legend")

p2 <- p + guides(colour = guide_colorbar(), size = guide_legend(),
           shape = guide_legend())

p3 <- p +
  scale_colour_continuous(guide = "colorbar") +
  scale_size_discrete(guide = "legend") +
  scale_shape(guide = "legend")

再比如,刪除某一圖例或整合所有圖例

# 刪除圖例
p1 <- p + guides(colour = "none")

p2 <- p + guides(colour = "colorbar",size = "none")

# 整合圖例
p3 <- p + guides(colour = guide_legend("title"), size = guide_legend("title"),
           shape = guide_legend("title"))
# 與上面的代碼等價(jià)
g <- guide_legend("title")
p4 <- p + guides(colour = g, size = g, shape = g)

plot_grid(p1, p2, p3, p4, labels = LETTERS[1:4], ncol = 2)

1. 圖例符號(hào)

在之前的繪制中递胧,通常圖例會(huì)根據(jù)幾何對(duì)象來(lái)生成圖例碑韵。例如上圖中,點(diǎn)圖的圖例符號(hào)也是點(diǎn)缎脾。

我們可以為 key_glyph 參數(shù)設(shè)置不同的 draw_key_*() 函數(shù)來(lái)自定義圖例符號(hào)祝闻,其中 * 號(hào)表示的是各種符號(hào)。

p <- ggplot(economics, aes(date, psavert, color = "savings rate"))

p1 <- p + geom_line()

# 通過(guò)指定字符串名稱
p2 <- p + geom_line(key_glyph = "timeseries")
# 或者對(duì)應(yīng)的函數(shù)名
p3 <- p + geom_line(key_glyph = draw_key_timeseries)

# 其他形狀
p4 <- p + geom_line(key_glyph = draw_key_rect)

plot_grid(p1, p2, p3, p4, labels = LETTERS[1:4],
          nrow = 2)

2. 顏色條

簡(jiǎn)單的顏色條可以通過(guò) scale_fill 和 scale_colour 的 guide 參數(shù)來(lái)設(shè)置

df <- expand.grid(X1 = 1:10, X2 = 1:10)
df$value <- df$X1 * df$X2

p1 <- ggplot(df, aes(X1, X2)) + geom_tile(aes(fill = value))
# 使用字符串名稱
p1 + scale_fill_continuous(guide = "colourbar")
# 或者對(duì)應(yīng)的函數(shù)
p1 + scale_fill_continuous(guide = guide_colourbar())

相當(dāng)于下面的代碼

p1 + guides(fill = guide_colourbar())

guide_colourbar 函數(shù)的參數(shù)非常多

guide_colourbar(
  title = waiver(),
  title.position = NULL,
  title.theme = NULL,
  title.hjust = NULL,
  title.vjust = NULL,
  label = TRUE,
  label.position = NULL,
  label.theme = NULL,
  label.hjust = NULL,
  label.vjust = NULL,
  barwidth = NULL,
  barheight = NULL,
  nbin = 300,
  raster = TRUE,
  frame.colour = NULL,
  frame.linewidth = 0.5,
  frame.linetype = 1,
  ticks = TRUE,
  ticks.colour = "white",
  ticks.linewidth = 0.5,
  draw.ulim = TRUE,
  draw.llim = TRUE,
  direction = NULL,
  default.unit = "line",
  reverse = FALSE,
  order = 0,
  available_aes = c("colour", "color", "fill"),
  ...
)

我們對(duì)部分參數(shù)進(jìn)行說(shuō)明遗菠,如設(shè)置顏色條的大小联喘、刪除標(biāo)簽或刻度、調(diào)整標(biāo)簽的位置以及設(shè)置標(biāo)簽的主題

# 設(shè)置大小
p2 <- p1 + guides(fill = guide_colourbar(barwidth = 0.5, barheight = 10))
# 刪除標(biāo)簽
p3 <- p1 + guides(fill = guide_colourbar(label = FALSE))
# 刪除刻度
p4 <- p1 + guides(fill = guide_colourbar(ticks = FALSE))
# 調(diào)整標(biāo)簽位置
p5 <- p1 + guides(fill = guide_colourbar(label.position = "left"))
# 設(shè)置標(biāo)簽主題
p6 <- p1 + guides(fill = guide_colourbar(label.theme = element_text(colour = "blue", angle = 0)))

plot_grid(p1, p2, p3, p4, p5, p6, labels = LETTERS[1:6],
          nrow = 3)

設(shè)置顏色條每個(gè)刻度間的分箱個(gè)數(shù)辙纬,分箱越多豁遭,顏色條看起來(lái)越平滑

# 顏色條的分箱個(gè)數(shù),越大越平滑
p7 <- p1 + guides(fill = guide_colourbar(nbin = 3))

p8 <- p1 + guides(fill = guide_colourbar(nbin = 100))

plot_grid(p7, p8, labels = LETTERS[1:2])

如果存在多個(gè)圖例贺拣,可以分別對(duì)每個(gè)圖例進(jìn)行獨(dú)立的設(shè)置

p2 <- p1 + geom_point(aes(size = value))
# 多個(gè)圖例堤框,可以分開獨(dú)立控制
p3 <- p2 +
  scale_fill_continuous(guide = "colourbar") +
  scale_size(guide = "legend")
# 或者使用字符串名稱
p3 <- p2 + guides(fill = "colourbar", size = "legend")

p4 <- p2 +
  scale_fill_continuous(guide = guide_colourbar(direction = "horizontal")) +
  scale_size(guide = guide_legend(direction = "vertical"))

plot_grid(p3, p4, labels = LETTERS[1:2])

3. 基本圖例設(shè)置

也可以使用 guide_legend 函數(shù)來(lái)設(shè)置圖例的樣式,該函數(shù)也有很多參數(shù)可供選擇

guide_legend(
  title = waiver(),
  title.position = NULL,
  title.theme = NULL,
  title.hjust = NULL,
  title.vjust = NULL,
  label = TRUE,
  label.position = NULL,
  label.theme = NULL,
  label.hjust = NULL,
  label.vjust = NULL,
  keywidth = NULL,
  keyheight = NULL,
  direction = NULL,
  default.unit = "line",
  override.aes = list(),
  nrow = NULL,
  ncol = NULL,
  byrow = FALSE,
  reverse = FALSE,
  order = 0,
  ...
)

例如纵柿,下面的代碼只繪制了一個(gè)簡(jiǎn)單的圖例

df <- expand.grid(X1 = 1:10, X2 = 1:10)
df$value <- df$X1 * df$X2

p1 <- ggplot(df, aes(X1, X2)) + geom_tile(aes(fill = value))

p1 + scale_fill_continuous(guide = guide_legend())

我們可以為它設(shè)置各種樣式,如

# 設(shè)置圖例標(biāo)題的位置
p2 <- p1 + guides(fill = guide_legend(title = "LEFT", title.position = "left"))

# 使用 element_text 設(shè)置圖例標(biāo)題的樣式
p3 <- p1 + guides(fill =
              guide_legend(
                title.theme = element_text(
                  size = 15,
                  face = "italic",
                  colour = "red",
                  angle = 0
                )
              )
)

# 設(shè)置標(biāo)簽的位置
p4 <- p1 + guides(fill = guide_legend(label.position = "left", label.hjust = 1))

# 設(shè)置標(biāo)簽的樣式
p5 <- p1 + scale_fill_continuous(breaks = c(5, 10, 15),
                           labels = paste("long", c(5, 10, 15)),
                           guide = guide_legend(
                             direction = "horizontal",
                             title.position = "top",
                             label.position = "bottom",
                             label.hjust = 0.5,
                             label.vjust = 1,
                             label.theme = element_text(angle = 90)
                           )
)

plot_grid(p2, p3, p4, p5, labels = LETTERS[1:4], nrow = 2)

也可以覆蓋原理的屬性映射

p3 <- ggplot(mtcars, aes(vs, am, colour = factor(cyl))) +
  geom_jitter(alpha = 1/5, width = 0.01, height = 0.01)

# override.aes overwrites the alpha
p4 <- p3 + guides(colour = guide_legend(override.aes = list(alpha = 1)))

plot_grid(p3, p4, labels = LETTERS[1:2])

在圖 A 中启绰,點(diǎn)的透明度太低了昂儒,看起來(lái)挺費(fèi)勁的。然后在圖 B 中委可,我們將透明度 alpha 設(shè)置為 1渊跋,更容易分辨不同類型的點(diǎn)。

對(duì)于某些圖着倾,由于類別太多導(dǎo)致圖例非常的長(zhǎng)拾酝,例如

df <- data.frame(x = 1:20, y = 1:20, color = letters[1:20])
p <- ggplot(df, aes(x, y)) +
  geom_point(aes(colour = color))
p

我們可以限制圖例的行列數(shù)

# 限制行列的數(shù)目
p1 <- p + guides(col = guide_legend(nrow = 8))

p2 <- p + guides(col = guide_legend(ncol = 8))

p3 <- p + guides(col = guide_legend(nrow = 8, byrow = TRUE))

# 將順序反轉(zhuǎn)
p4 <- p + guides(col = guide_legend(reverse = TRUE))

plot_grid(p1, p2, p3, p4, labels = LETTERS[1:4], ncol = 2)

讓圖例看起來(lái)更好看些。

我們?cè)趫D D 中卡者,設(shè)置 reverse = TRUE 可以將標(biāo)簽順序進(jìn)行反轉(zhuǎn)

4. 基本坐標(biāo)軸設(shè)置

坐標(biāo)軸的設(shè)置通常與 scale_(x|y)_continuous()scale_(x|y)_discrete() 兩個(gè)標(biāo)度函數(shù)搭配使用

guide_axis(
  title = waiver(),
  check.overlap = FALSE,
  angle = NULL,
  n.dodge = 1,
  order = 0,
  position = waiver()
)

例如

p <- ggplot(mpg, aes(cty * 100, hwy * 100)) +
  geom_point()
# 設(shè)置標(biāo)簽的行數(shù)(如果要設(shè)置列蒿囤,需要傳入一個(gè)向量)
p1 <- p + scale_x_continuous(guide = guide_axis(n.dodge = 2))
# 設(shè)置標(biāo)簽的角度
p2 <- p + guides(x = guide_axis(angle = 90))
# 復(fù)制一個(gè)軸
p3 <- p + guides(x = guide_axis(n.dodge = 2), y.sec = guide_axis())

plot_grid(p, p1, p2, p3, labels = LETTERS[1:4], ncol = 2)

5. 分箱圖例

分箱圖例使用 guide_bins 函數(shù)來(lái)設(shè)置,它是 guide_legend() 的分箱版本崇决,通常需要和分箱的標(biāo)度函數(shù)一起使用

如果你想要將其搭配離散型數(shù)據(jù)使用材诽,需要確保離散數(shù)據(jù)的 level 必須遵從 base::cut 函數(shù)的命名規(guī)則底挫,即名稱必須為 (<lower>, <upper>] 形式

示例

p <- ggplot(mtcars) +
  geom_point(aes(disp, mpg, size = hp)) +
  scale_size_binned()

# 刪除軸或樣式
p1 <- p + guides(size = guide_bins(axis = FALSE))
# 顯示分箱區(qū)間
p2 <- p + guides(size = guide_bins(show.limits = TRUE))
# 設(shè)置軸的箭頭
p3 <- p + guides(size = guide_bins(
  axis.arrow = arrow(length = unit(1.5, 'mm'), ends = 'both')
))

# 默認(rèn)會(huì)盡可能將圖例合并
p4 <- ggplot(mtcars) +
  geom_point(aes(disp, mpg, size = hp, colour = hp)) +
  scale_size_binned() +
  scale_colour_binned(guide = "bins")

plot_grid(p1, p2, p3, p4, labels = LETTERS[1:4], ncol = 2)

6. 分箱顏色條

分箱顏色條 guide_coloursteps 是 guide_colourbar() 的分箱版,它將斷點(diǎn)之間的區(qū)域顯示為一個(gè)固定的顏色

例如脸侥,

df <- expand.grid(X1 = 1:10, X2 = 1:10)
df$value <- df$X1 * df$X2

p <- ggplot(df, aes(X1, X2)) + geom_tile(aes(fill = value))

p1 <- p + scale_fill_binned()
# 默認(rèn)是等間距的斷點(diǎn)建邓,可以自定義斷點(diǎn)
p2 <- p + scale_fill_binned(breaks = c(10, 25, 50))

# 根據(jù)區(qū)間的數(shù)據(jù)占比顯示長(zhǎng)度
p3 <- p + scale_fill_binned(
  breaks = c(10, 25, 50),
  guide = guide_coloursteps(even.steps = FALSE)
)
# 是否顯示所有刻度(外圍的刻度)
p4 <- p + scale_fill_binned(guide = guide_coloursteps(show.limits = TRUE))

plot_grid(p1, p2, p3, p4, labels = LETTERS[1:4], ncol = 2)

7. 設(shè)置次軸

sec_axis 和 dup_axis 函數(shù)與位置標(biāo)度一起使用,來(lái)創(chuàng)建與主軸相對(duì)的次軸睁枕。

副軸必須基于主軸的一對(duì)一變換

sec_axis(
  trans = NULL,
  name = waiver(),
  breaks = waiver(),
  labels = waiver(),
  guide = waiver()
)

dup_axis(
  trans = ~.,
  name = derive(),
  breaks = derive(),
  labels = derive(),
  guide = derive()
)

sec_axis() 需要一個(gè)轉(zhuǎn)換函數(shù)傳遞給 trans 參數(shù)官边,其他所有設(shè)置可以使用 derive() 從主軸繼承

dup_axis() 創(chuàng)建一個(gè)主軸的拷貝作為次軸

示例

p <- ggplot(mtcars, aes(cyl, mpg)) +
  geom_point()

# 創(chuàng)建一個(gè)簡(jiǎn)單的次軸
p1 <- p + scale_y_continuous(sec.axis = sec_axis(~ . + 10))

# 從主軸中繼承名稱
p2 <- p + scale_y_continuous("Miles/gallon", sec.axis = sec_axis(~ . + 10, name = derive()))

# 復(fù)制一份主軸
p3 <- p + scale_y_continuous(sec.axis = dup_axis())

# 設(shè)置轉(zhuǎn)換函數(shù)
p4 <- p + scale_y_continuous(sec.axis = ~ .^2)

plot_grid(p1, p2, p3, p4, labels = LETTERS[1:4],
          nrow = 2)

創(chuàng)建時(shí)間次軸

df <- data.frame(
  dx = seq(as.POSIXct("2012-02-29 12:00:00",
                      tz = "UTC",
                      format = "%Y-%m-%d %H:%M:%S"
  ),
  length.out = 10, by = "4 hour"
  ),
  price = seq(20, 200000, length.out = 10)
)

ggplot(df, aes(x = dx, y = price)) + geom_line() +
  scale_x_datetime("Date", date_labels = "%b %d",
  date_breaks = "6 hour",
  sec.axis = dup_axis(name = "Time of Day",
  labels = scales::time_format("%I %p")))

轉(zhuǎn)換為不同的時(shí)區(qū)顯示

ggplot(df, aes(x = dx, y = price)) + geom_line() +
  scale_x_datetime("GMT", date_labels = "%b %d %I %p",
  sec.axis = sec_axis(~ . + 8 * 3600, name = "GMT+8",
  labels = scales::time_format("%b %d %I %p")))
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市外遇,隨后出現(xiàn)的幾起案子注簿,更是在濱河造成了極大的恐慌,老刑警劉巖臀规,帶你破解...
    沈念sama閱讀 212,222評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件滩援,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡塔嬉,警方通過(guò)查閱死者的電腦和手機(jī)玩徊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,455評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)谨究,“玉大人恩袱,你說(shuō)我怎么就攤上這事〗赫埽” “怎么了畔塔?”我有些...
    開封第一講書人閱讀 157,720評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)鸯屿。 經(jīng)常有香客問(wèn)我澈吨,道長(zhǎng),這世上最難降的妖魔是什么寄摆? 我笑而不...
    開封第一講書人閱讀 56,568評(píng)論 1 284
  • 正文 為了忘掉前任谅辣,我火速辦了婚禮,結(jié)果婚禮上婶恼,老公的妹妹穿的比我還像新娘桑阶。我一直安慰自己,他們只是感情好勾邦,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,696評(píng)論 6 386
  • 文/花漫 我一把揭開白布蚣录。 她就那樣靜靜地躺著,像睡著了一般眷篇。 火紅的嫁衣襯著肌膚如雪萎河。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,879評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音公壤,去河邊找鬼换可。 笑死,一個(gè)胖子當(dāng)著我的面吹牛厦幅,可吹牛的內(nèi)容都是我干的沾鳄。 我是一名探鬼主播,決...
    沈念sama閱讀 39,028評(píng)論 3 409
  • 文/蒼蘭香墨 我猛地睜開眼确憨,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼译荞!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起休弃,我...
    開封第一講書人閱讀 37,773評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤吞歼,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后塔猾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體篙骡,經(jīng)...
    沈念sama閱讀 44,220評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,550評(píng)論 2 327
  • 正文 我和宋清朗相戀三年丈甸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了糯俗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,697評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡睦擂,死狀恐怖得湘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情顿仇,我是刑警寧澤淘正,帶...
    沈念sama閱讀 34,360評(píng)論 4 332
  • 正文 年R本政府宣布,位于F島的核電站臼闻,受9級(jí)特大地震影響鸿吆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜述呐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,002評(píng)論 3 315
  • 文/蒙蒙 一伞剑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧市埋,春花似錦、人聲如沸恕刘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,782評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)褐着。三九已至坷澡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間含蓉,已是汗流浹背频敛。 一陣腳步聲響...
    開封第一講書人閱讀 32,010評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工项郊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人斟赚。 一個(gè)月前我還...
    沈念sama閱讀 46,433評(píng)論 2 360
  • 正文 我出身青樓着降,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親拗军。 傳聞我的和親對(duì)象是個(gè)殘疾皇子任洞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,587評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容