R 數(shù)據(jù)可視化 —— grid 系統(tǒng)(一)

前言

R 中主要存在兩種繪圖系統(tǒng):

  • base R 傳統(tǒng)圖像系統(tǒng)
  • grid 圖像系統(tǒng)

傳統(tǒng)的圖像系統(tǒng)是由 graphics 包所提供的一系列函數(shù)組成黍匾,grid 系統(tǒng)是 grid 包提供的

grid 包是一個(gè)底層的繪圖系統(tǒng),提供的都是底層的繪圖函數(shù)踢步,沒有用于繪制復(fù)雜圖形的高級函數(shù)。

ggplot2lattice 兩個(gè)頂層的繪圖包都是基于 grid 系統(tǒng)的鲁沥,所以酒唉,了解 grid 包對于理解 ggplot2 的頂層函數(shù)的工作方式是很有幫助的

同時(shí),也可以使用 grid 包來靈活地控制圖形的外觀和布局

安裝導(dǎo)入

install.packages("grid")
library(grid)

grid 圖像模型

1. 圖形原語

grid 提供了一些函數(shù)用于繪制簡單的圖形软族,例如

這些函數(shù)被稱為圖形原語,使用這些函數(shù)可以直接繪制對應(yīng)的圖形残制,例如

grid.text(label = "Let's us begin!")
grid.circle(
  x=seq(0.1, 0.9, length=100),
  y=0.5 + 0.4*sin(seq(0, 2*pi, length=100)),
  r=abs(0.1*cos(seq(0, 2*pi, length=100)))
)

2. 坐標(biāo)系統(tǒng)

grid 的坐標(biāo)系統(tǒng)是用來確定數(shù)值的單位互订,同樣的數(shù)值在不同的單位中表示不同的大小,看起來叫單位系統(tǒng)應(yīng)該會(huì)更恰當(dāng)些

坐標(biāo)系統(tǒng)如下


使用 unit 函數(shù)來設(shè)置不同的系統(tǒng)

> unit(1, "cm")
[1] 1cm
> unit(1:4, "mm")
[1] 1mm 2mm 3mm 4mm
> unit(1:4, c("npc", "mm", "native", "lines"))
[1] 1npc    2mm     3native 4lines 

坐標(biāo)系統(tǒng)之間的運(yùn)算將會(huì)以表達(dá)式的方式返回

> unit(1:4, "mm")[1] - unit(1:4, "mm")[4]
[1] 1mm-4mm
> unit(1, "npc") - unit(1:4, "mm")
[1] 1npc-1mm 1npc-2mm 1npc-3mm 1npc-4mm
> max(unit(1:4, c("npc", "mm", "native", "lines")))
[1] max(1npc, 2mm, 3native, 4lines)

對于字符串及對象長度坐標(biāo)系統(tǒng)

> unit(1, "strwidth", "some text")
[1] 1strwidth
> unit(1, "grobwidth", textGrob("some text"))
[1] 1grobwidth

有對應(yīng)的簡便函數(shù)可以使用

> stringHeight("some text")
[1] 1strheight
> grobHeight(textGrob("some text"))
[1] 1grobheight

可以使用 convertWidthconvertHeight 實(shí)現(xiàn)單位之間的轉(zhuǎn)換

> convertHeight(unit(1, "cm"), "mm")
[1] 10mm
> convertHeight(unit(1, "dida"), "points")
[1] 1.07000864304235points
> convertHeight(unit(1, "cicero"), "points")
[1] 12.8401037165082points
> convertHeight(unit(1, "cicero"), "dida")
[1] 12dida
> convertHeight(unit(1, "points"), "scaledpts")
[1] 65536scaledpts
> convertWidth(stringWidth("some text"), "lines")
[1] 3.61246744791667lines
> convertWidth(stringWidth("some text"), "inches")
[1] 0.722493489583333inches

對于一個(gè)圖形對象痘拆,如果修改了圖形對象屬性,則對應(yīng)的大小也會(huì)改變

> grid.text("some text", name="tgrob")
> convertWidth(grobWidth("tgrob"), "inches")
[1] 0.722493489583333inches
# 修改圖形對象的 fontsize 屬性
> grid.edit("tgrob", gp=gpar(fontsize=18))
> convertWidth(grobWidth("tgrob"), "inches")
[1] 1.083740234375inches

我們可以使用不同的單位系統(tǒng)來繪制一個(gè)矩形

grid.rect(
  x=unit(0.5, "npc"), 
  y=unit(1, "inches"),
  width=stringWidth("very snug"), 
  height=unit(1, "lines"), 
  just=c("left", "bottom")
)

3. gpar

所有的圖形原語函數(shù)都有一個(gè) gp(graphical parameters) 參數(shù)氮墨,用來接收一個(gè) gpar 對象纺蛆,該對象包含一些圖形參數(shù)用于控制圖像的輸出

gpar 對象可以使用 gpar() 函數(shù)來生成,例如

> gpar(col="red", lty="dashed")
$col
[1] "red"

$lty
[1] "dashed"

這些圖形參數(shù)包括

使用 get.gpar 可以獲取當(dāng)前圖形參數(shù)的值规揪,如果未指定要獲取的參數(shù)桥氏,將會(huì)返回所有的參數(shù)值

> get.gpar(c("lty", "fill"))
$lty
[1] "solid"

$fill
[1] "white"

因此,我們可以在繪制圖像時(shí)猛铅,傳遞 gp 參數(shù)來設(shè)置圖像參數(shù)

grid.rect(
  x=0.66, 
  height=0.7, 
  width=0.2,
  gp=gpar(fill="blue")
)

grid.rect(
  x=0.33, 
  height=0.7, 
  width=0.2
)

grid 中字支,cex 參數(shù)是累積的,也就是說當(dāng)前的 cex 值等于當(dāng)前設(shè)置的值乘上之前的 cex

例如

pushViewport(viewport(gp=gpar(cex=0.5)))

grid.text("How small do you think?", gp=gpar(cex=0.5))

在一個(gè) viewport 中設(shè)置了 cex = 0.5,之后的文本又設(shè)置了 cex = 0.5堕伪,最后文本的大小就是 0.5*0.5 = 0.25

alpha 參數(shù)與 cex 類似揖庄,也是累積的

注意: 這些圖形參數(shù)都可以接受一個(gè)向量值,比如欠雌,你可以將一個(gè)顏色向量傳遞給 colfill 參數(shù)蹄梢,如果向量的長度小于繪制的圖形的個(gè)數(shù),則參數(shù)會(huì)進(jìn)行循環(huán)賦值

如富俄,我們繪制 100 個(gè)圓形禁炒,但是只傳遞了一個(gè)長度為 50 的顏色向量給 col 參數(shù)

grid.circle(
  x = seq(0.1, 0.9, length=100),
  y = 0.5 + 0.4*sin(seq(0, 2*pi, length=100)),
  r = abs(0.1*cos(seq(0, 2*pi, length=100))),
  gp = gpar(col=rainbow(50))
  )

對于多邊形 grid.polygon() 函數(shù),有一個(gè) id 參數(shù)可以將多邊形的點(diǎn)進(jìn)行分組霍比,如果某一分組點(diǎn)中包含 NA 值幕袱,則又會(huì)將在 NA 處將點(diǎn)分為兩組

# 設(shè)置均等分的角度,并刪除最后一個(gè)角度
angle <- seq(0, 2*pi, length=11)[-11]

grid.polygon(
  x = 0.25 + 0.2*cos(angle), 
  y = 0.5 + 0.3*sin(angle),
  id = rep(1:2, c(7, 3)),
  gp = gpar(
    fill=c("grey", "white")
    )
  )

# 將其中一個(gè)角度設(shè)置為 NA
angle[4] <- NA

grid.polygon(
  x = 0.75 + 0.2*cos(angle), 
  y = 0.5 + 0.3*sin(angle),
  id = rep(1:2, c(7, 3)),
  gp = gpar(
    fill=c("grey", "white")
    )
  )

從圖中可以看出悠瞬,本來根據(jù) id 值分為兩組们豌,第一組為灰色填充,第二組為白色填充阁危。

但是在添加 NA 之后玛痊,在 NA 處將 id1 的分組又一分為二,但是填充色還是灰色狂打,并不是接續(xù)白色

4. viewport

grid 中擂煞,圖像的繪制需要在畫布中執(zhí)行,也就是在繪制圖像時(shí)需要新建一個(gè)畫布

grid.newpage()

通常使用 grid.newpage() 函數(shù)來新建一個(gè)空白畫布

在畫布中趴乡,又可以定義很多個(gè)獨(dú)立的矩形繪圖窗口对省,在每個(gè)矩形窗口中都可以繪制任意你想要繪制的內(nèi)容,這樣的窗口就是 viewport

默認(rèn)情況下晾捏,整個(gè)畫布就是一個(gè) viewport蒿涎,如果新增一個(gè) viewport,那么默認(rèn)會(huì)繼承所有默認(rèn)的圖形參數(shù)值

使用 viewport() 函數(shù)來新建一個(gè) viewport惦辛,并接受位置參數(shù)(xy) 和大小參數(shù)(widthheight)劳秋,以及對齊方式(just)

> viewport(
+   x = unit(0.4, "npc"), 
+   y = unit(1, "cm"),
+   width = stringWidth("very very snug indeed"), 
+   height = unit(6, "lines"), 
+   just = c("left", "bottom")
+   )
viewport[GRID.VP.4] 

viewport() 函數(shù)返回的是一個(gè) viewport 對象,但其實(shí)你會(huì)發(fā)現(xiàn)胖齐,什么東西都沒有畫出來

因?yàn)椴J纾瑒?chuàng)建了一個(gè) viewport 對象區(qū)域之后,需要將其 push 到圖像設(shè)備中

其位置大致應(yīng)該是這樣的


4.1 viewport 的切換

pushViewport() 函數(shù)可以將一個(gè) viewport 對象 push 到圖像設(shè)備中呀伙,例如

grid.text(
  "top-left corner", 
  x=unit(1, "mm"),
  y=unit(1, "npc") - unit(1, "mm"),
  just=c("left", "top")
  )

pushViewport(
  viewport(
    width=0.8, 
    height=0.5, 
    angle=10,
    name="vp1"
    )
  )

grid.rect()

grid.text(
  "top-left corner", 
  x = unit(1, "mm"),
  y = unit(1, "npc") - unit(1, "mm"),
  just = c("left", "top")
  )

我們在最外層畫布的左上角添加一串文本补履,然后添加一個(gè) viewport,同時(shí)繪制外側(cè)矩形框剿另,并旋轉(zhuǎn) 10 度箫锤,也在左上角添加一串文本

在當(dāng)前 viewport 的基礎(chǔ)上贬蛙,還可以在新建 viewport,新 pushviewport 將會(huì)相對于當(dāng)前 viewport 的位置來放置

pushViewport(
  viewport(
    width=0.8, 
    height=0.5, 
    angle=10,
    name="vp2"
    )
  )

grid.rect()

grid.text(
  "top-left corner", 
  x = unit(1, "mm"),
  y = unit(1, "npc") - unit(1, "mm"),
  just = c("left", "top")
  )

每次 push 一個(gè) viewport 之后谚攒,都會(huì)將該 viewport 作為當(dāng)前活動(dòng)的窗口阳准,如果要回滾到之前的 viewport,可以使用 popViewport() 函數(shù)五鲫,該函數(shù)會(huì)將當(dāng)前活動(dòng)窗口刪除

popViewport()

grid.text(
  "bottom-right corner",
  x=unit(1, "npc") - unit(1, "mm"),
  y=unit(1, "mm"), 
  just=c("right", "bottom")
  )

從圖片中可以看到溺职,活動(dòng)窗口已經(jīng)切換到第二個(gè) viewport,并將文本繪制在其右下角

popViewport() 還可接受一個(gè)參數(shù) n位喂,用于指定需要 pop 幾個(gè) viewport浪耘。默認(rèn) n = 1,傳遞更大的值可以跳轉(zhuǎn)到更上層的 viewport塑崖,如果設(shè)置為 0 則會(huì)返回到最外層圖形設(shè)備上七冲。

另一個(gè)更改活動(dòng)窗口的方法是,使用 upViewport()downViewport() 函數(shù)规婆。

upViewport() 函數(shù)與 popViewport() 類似澜躺,不同之處在于,upViewport() 函數(shù)不會(huì)刪除當(dāng)前活動(dòng) viewport抒蚜。

這樣掘鄙,在重新訪問之前的 viewport 時(shí),不用再 push 一遍嗡髓,而且能夠提升訪問的速度操漠。

重新訪問 viewport 使用的是 downViewport() 函數(shù),通過 name 參數(shù)來選擇指定的 viewport

# 切換到最外層
upViewport()
# 在右下角添加文本
grid.text(
  "bottom-right corner",
  x=unit(1, "npc") - unit(1, "mm"),
  y=unit(1, "mm"), 
  just=c("right", "bottom")
  )
# 返回 vp1
downViewport("vp1")
# 添加外側(cè)框線
grid.rect(
  width=unit(1, "npc") + unit(2, "mm"), 
  height=unit(1, "npc") + unit(2, "mm"),
  gp = gpar(fill = NA)
  )

如果想要訪問 vp2 會(huì)報(bào)錯(cuò)饿这,不存在該 viewport

> downViewport("vp2")
Error in grid.Call.graphics(C_downviewport, name$name, strict) : 
  Viewport 'vp2' was not found

還可以直接使用 seekViewport() 函數(shù)來切換到指定名稱的 viewport

4.2 裁剪 viewport

我們可以將圖形限制在當(dāng)前 viewport 之內(nèi)浊伙,如果繪制的圖形大小超過了當(dāng)前 viewport 則不會(huì)顯示,我們可以使用 clip 參數(shù)

該參數(shù)接受三個(gè)值:

  • on:輸出的圖形必須保持在當(dāng)前 viewport 內(nèi)长捧,超出的部分會(huì)被裁剪
  • inherit:繼承上一個(gè) viewportclip
  • off:不會(huì)被裁剪

例如

grid.newpage()
# 在畫布中心添加一個(gè) viewport嚣鄙,并設(shè)置允許剪切
pushViewport(viewport(w=.5, h=.5, clip="on"))
# 添加矩形框和線條很粗的圓形
grid.rect(
  gp = gpar(fill = "#8dd3c7")
  )
grid.circle(
  r = .7, 
  gp = gpar(
    lwd = 20,
    col = "#fdb462"
    )
)

# 在當(dāng)前 viewport 中添加一個(gè) viewport,繼承方式
pushViewport(viewport(clip="inherit"))
# 添加線條更細(xì)一點(diǎn)的圓形
grid.circle(
  r = .7, 
  gp = gpar(
    lwd = 10, 
    col = "#80b1d3",
    fill = NA)
)
# 關(guān)閉裁剪
pushViewport(viewport(clip="off"))
# 顯示整個(gè)圓形
grid.circle(
  r=.7,
  gp = gpar(
    fill = NA,
    col = "#fb8072"
  )
)

只有最后一個(gè)圓顯示出了全部串结,前面兩個(gè)圓形只顯示在 viewport 內(nèi)的部分

4.3 viewport 的排列

viewport 的排布方式有三種:

  • vpListviewport 列表哑子,以平行的方式排列各 viewport
  • vpStack:以堆疊的方式排列,俗稱套娃肌割,與使用 pushViewport 功能相似
  • vpTree:以樹的方式排列卧蜓,一個(gè)根節(jié)點(diǎn)可以有任意個(gè)子節(jié)點(diǎn)

例如,我們新建三個(gè) viewport

vp1 <- viewport(name="A")
vp2 <- viewport(name="B")
vp3 <- viewport(name="C")

然后声功,我們以列表的方式將這些 viewport push 到圖形設(shè)備中

pushViewport(vpList(vp1, vp2, vp3))

可以使用 current.vpTree 函數(shù)來查看當(dāng)前的 viewport 排列樹

> current.vpTree()
viewport[ROOT]->(viewport[A], viewport[B], viewport[C]) 

可以看到,這三個(gè) viewport 是并列的關(guān)系

我們再看看以堆疊的方式放置

> grid.newpage()
> pushViewport(vpStack(vp1, vp2, vp3))
> current.vpTree()
viewport[ROOT]->(viewport[A]->(viewport[B]->(viewport[C]))) 

可以看到宠叼,根節(jié)點(diǎn)是整個(gè)畫布先巴,畫布的子節(jié)點(diǎn)是 A其爵,A 的子節(jié)點(diǎn)是 BB 的子節(jié)點(diǎn)是 C伸蚯,這就是堆疊的方式摩渺,一個(gè)套一個(gè)

那對于樹形排列也就不難理解了

> grid.newpage()
> pushViewport(vpTree(vp1, vpList(vp2, vp3)))
> current.vpTree()
viewport[ROOT]->(viewport[A]->(viewport[B], viewport[C]))

根節(jié)點(diǎn)是整個(gè)畫布,然后是子節(jié)點(diǎn) A界轩,A 的子節(jié)點(diǎn)是 B炮温、C

我們知道殖熟,畫布中的所有 viewport 是以樹的方式存儲(chǔ)的,那么我們就可以根據(jù) viewport 的父節(jié)點(diǎn)來定位某一個(gè) viewport

例如绰姻,我們想查找名稱 Cviewport,其父節(jié)點(diǎn)為 B引瀑,再上層父節(jié)點(diǎn)為 A狂芋,則可以使用 vpPath 函數(shù)來構(gòu)造檢索路徑

> vpPath("A", "B", "C")
A::B::C 

同時(shí)也可以消除同名 viewport 的干擾

4.4 將 viewport 作為圖形原語的參數(shù)

每個(gè)原語函數(shù)都有一個(gè) vp 參數(shù)

例如,在一個(gè) viewport 中繪制文本

vp1 <- viewport(width=0.5, height=0.5, name="vp1")
pushViewport(vp1)

grid.text("Text drawn in a viewport")
popViewport()

也可以下面的代碼代替憨栽,將文本繪制到指定的 viewport

grid.text("Text drawn in a viewport", vp=vp1)

4.5 viewport 的圖形參數(shù)

viewport 也有一個(gè) gp 參數(shù)帜矾,用來設(shè)置圖形屬性,設(shè)置的值將會(huì)作為 viewport 中所有的圖形對象的默認(rèn)值

grid.newpage()

pushViewport(
  viewport(
    gp = gpar(fill="grey")
    )
  )

grid.rect(
  x = 0.33, 
  height = 0.7, 
  width = 0.2
  )
grid.rect(
  x = 0.66, 
  height = 0.7, 
  width = 0.2,
  gp = gpar(fill="black")
  )

popViewport()

4.6 布局

viewportlayout 參數(shù)可以用來設(shè)置布局屑柔,將 viewport 區(qū)域分割成不同的行和列屡萤,行之間可以有不同的高度,列之間可以有不同的寬度掸宛。

grid 布局使用 grid.layout() 函數(shù)來構(gòu)造死陆,例如

vplay <- grid.layout(
  nrow = 3, 
  ncol = 3, 
  respect=rbind(
    c(0, 0, 0),
    c(0, 1, 0),
    c(0, 0, 0))
  )

我們構(gòu)造了一個(gè) 33 列的布局,中間的位置是一個(gè)正方形

構(gòu)造了布局之后旁涤,就可以添加到 viewport 中了

pushViewport(viewport(layout=vplay))

我們可以使用 layout.pos.collayout.pos.row 參數(shù)來指定 viewport 放置的位置

# 新建一個(gè) viewport 并放置在第二列
pushViewport(
  viewport(
    layout.pos.col = 2, 
    name = "col2")
  )
grid.rect(
  gp = gpar(
    lwd = 10,
    col = "black",
    fill = NA
  ))
grid.text(
  label = "col2",
  x = unit(1, "mm"),
  y = unit(1, "npc") - unit(1, "mm"),
  just = c("left", "top")
  )

upViewport()

# 新建一個(gè) viewport 并放置在第二行
pushViewport(
  viewport(
    layout.pos.row = 2, 
    name = "row2")
  )

grid.rect(
  gp = gpar(
    lwd = 10,
    col = "grey",
    fill = NA
  ))
grid.text(
  x = unit(1, "mm"),
  y = unit(1, "npc") - unit(1, "mm"),
  label = "row2",
  just = c("left", "top")
)

也可以使用 unit 來設(shè)置行列的高度和寬度翔曲,例如

unitlay <- grid.layout(
  nrow = 3, 
  ncol = 3, 
  widths = unit(
    c(1, 1, 2),
    c("inches", "null", "null")
  ),
  heights = unit(
    c(3, 1, 1),
    c("lines", "null", "null"))
  )

我們定義了一個(gè) 33 列的布局,列寬通過 widths 分配劈愚,即第一列寬度為 1 inches瞳遍,剩下的兩列的寬度的占比為 1:2

行高通過 heights 分配,第一行為 3 個(gè) lines 單位菌羽,剩下的兩行高度為 1:1

布局應(yīng)該是下圖這樣子的


grid 布局也可以嵌套

假設(shè)我們有這樣一個(gè)掠械,12 列的 viewport

gridfun <- function() { 
  # 1*2 的布局
  pushViewport(viewport(layout=grid.layout(1, 2))) 
  # 第一行第一列的 viewport
  pushViewport(viewport(layout.pos.col=1)) 
  # 繪制矩形和文本
  grid.rect(gp = gpar(fill = "#80b1d3")) 
  grid.text("black")
  grid.text("&", x=1)
  popViewport()
  # 第一行第二列的 viewport
  pushViewport(viewport(layout.pos.col=2, clip="on"))
  
  grid.rect(gp=gpar(fill="#fb8072"))
  grid.text("white", gp=gpar(col="white"))
  grid.text("&", x=0, gp=gpar(col="white"))
  
  popViewport(2)
}

新建一個(gè) 55 列的 viewport

pushViewport( 
  viewport(
    layout = grid.layout(
      nrow = 5, 
      ncol = 5, 
      widths=unit(
        c(5, 1, 5, 2, 5), 
        c("mm", "null", "mm", "null", "mm")),
      heights=unit(
        c(5, 1, 5, 2, 5), 
        c("mm", "null", "mm", "null", "mm"))
      )
    )
  )

然后,分別在 22 列和 44 列 中放置一個(gè) viewport

pushViewport(
  viewport(
    layout.pos.col=2, 
    layout.pos.row=2)
  )
gridfun()
popViewport()

pushViewport(
  viewport(
    layout.pos.col=4, 
    layout.pos.row=4)
  )
gridfun()
popViewport(2)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末注祖,一起剝皮案震驚了整個(gè)濱河市猾蒂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌是晨,老刑警劉巖肚菠,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異罩缴,居然都是意外死亡蚊逢,警方通過查閱死者的電腦和手機(jī)层扶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烙荷,“玉大人镜会,你說我怎么就攤上這事≈粘椋” “怎么了戳表?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長昼伴。 經(jīng)常有香客問我匾旭,道長,這世上最難降的妖魔是什么亩码? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任季率,我火速辦了婚禮,結(jié)果婚禮上描沟,老公的妹妹穿的比我還像新娘飒泻。我一直安慰自己,他們只是感情好吏廉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布泞遗。 她就那樣靜靜地躺著,像睡著了一般席覆。 火紅的嫁衣襯著肌膚如雪史辙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天佩伤,我揣著相機(jī)與錄音聊倔,去河邊找鬼。 笑死生巡,一個(gè)胖子當(dāng)著我的面吹牛耙蔑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播孤荣,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼甸陌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了盐股?” 一聲冷哼從身側(cè)響起钱豁,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎疯汁,沒想到半個(gè)月后牲尺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡幌蚊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年谤碳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了凛澎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,965評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡估蹄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出沫换,到底是詐尸還是另有隱情臭蚁,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布讯赏,位于F島的核電站垮兑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏漱挎。R本人自食惡果不足惜系枪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望磕谅。 院中可真熱鬧私爷,春花似錦、人聲如沸膊夹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽放刨。三九已至工秩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間进统,已是汗流浹背助币。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留螟碎,地道東北人眉菱。 一個(gè)月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像抚芦,于是被迫代替她去往敵國和親倍谜。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評論 2 355

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