TikZ là package dùng để vẽ hình rất mạnh trong (La)TeX, ta viết code để chỉ cho TeX cách thực hiện hình vẽ. Một số hình được vẽ bằng TikZ thuận tiện hơn vẽ bằng R. Do đó việc kế thừa các code mẫu đã có sử dụng TikZ vào trực tiếp trong file RMarkdown sẽ giúp bạn minh họa ý tưởng dễ dàng hơn và đỡ mất công vẽ lại trong R. Có 2 cách để dùng TikZ trong R như sau.

Cách 1: Vẽ trực tiếp trong code chunk

Sử dụng tham số extra.preamble cho phép đưa thêm package vào preamble của Tikz.

Nguồn: https://tex.stackexchange.com/questions/640061/simple-cartesian-plane-with-straight-lines

{tikz, engine.opts = list(extra.preamble = c("\\usepackage{tikz}", "\\usepackage{tzplot}")), fig.width = 5, fig.height = 5}
\begin{tikzpicture}
\tzaxes(-1,-1)(6,6){$x$}{$y$}
\tzticks*(-2pt:2pt){1,2,...,5}(-2pt:2pt){1,2,...,5}
\tzfn"AA"{\x-1}[-1:5]{$x-y=1$}[a]
\tzfn"BB"{-\x+3}[-1:4]
\tznode(0,3){$x+y=3$}[r]
\tzXpoint*{AA}{BB}{$P(2,1)$}[0]
\end{tikzpicture}

Cách 2: Dùng R để compile file .tex rồi insert file hình vào lại R

Ví dụ bạn có file .tex này chứa code để vẽ hình, bạn có thể copy nội dung này chạy lại bên một phần mềm compile LaTex khác để kiểm tra (mình sử dụng TeXworks). Cách này mình recommend vì render độc lập, giúp kết quả ra ổn hơn cách 1.

Nguồn: https://pgfplots.net/bell-curve/

\documentclass[border=3pt,tikz]{standalone} %[dvipsnames]

\usepackage{amsmath} % for \dfrac
\usepackage{tikz}
\tikzset{>=latex} % for LaTeX arrow head
\usepackage{pgfplots} % for the axis environment
\usepackage{xcolor}
\usepackage[outline]{contour} % halo around text
\contourlength{1.2pt}
\usetikzlibrary{positioning,calc}
\usetikzlibrary{backgrounds}% required for 'inner frame sep'
%\usepackage{adjustbox} % add whitespace (trim)

% define gaussian pdf and cdf
\pgfmathdeclarefunction{gauss}{3}{%
  \pgfmathparse{1/(#3*sqrt(2*pi))*exp(-((#1-#2)^2)/(2*#3^2))}%
}
\pgfmathdeclarefunction{cdf}{3}{%
  \pgfmathparse{1/(1+exp(-0.07056*((#1-#2)/#3)^3 - 1.5976*(#1-#2)/#3))}%
}
\pgfmathdeclarefunction{fq}{3}{%
  \pgfmathparse{1/(sqrt(2*pi*#1))*exp(-(sqrt(#1)-#2/#3)^2/2)}%
}
\pgfmathdeclarefunction{fq0}{1}{%
  \pgfmathparse{1/(sqrt(2*pi*#1))*exp(-#1/2))}%
}

\colorlet{mydarkblue}{blue!30!black}

% to fill an area under function
\usepgfplotslibrary{fillbetween}
\usetikzlibrary{patterns}
\pgfplotsset{compat=1.12} % TikZ coordinates <-> axes coordinates
% https://tex.stackexchange.com/questions/240642/add-vertical-line-of-equation-x-2-and-shade-a-region-in-graph-by-pgfplots

% plot aspect ratio
%\def\axisdefaultwidth{8cm}
%\def\axisdefaultheight{6cm}

% number of sample points
\def\N{50}
\begin{document}


% GAUSSIANs: p-value normal distributions
\begin{tikzpicture}[inner frame sep=0]
  \message{Normal distrubution p-value^^J}
  
  \def\q{5};
  \def\B{3};
  \def\S{8};
  \def\Bs{1.0};
  \def\Ss{1.5};
  \def\xmax{\B+3.2*\Bs};
  \def\ymin{{-0.15*gauss(\B,\B,\Bs)}};
  
  \begin{axis}[every axis plot post/.append style={
               mark=none,domain={-0.05*(\xmax)}:{1.08*\xmax},samples=\N,smooth},
               xmin={-0.1*(\xmax)}, xmax=\xmax,
               ymin=\ymin, ymax={1.1*gauss(\B,\B,\Bs)},
               axis lines=middle,
               axis line style=thick,
               enlargelimits=upper, % extend the axes a bit to the right and top
               ticks=none,
               xlabel=$x$,
               every axis x label/.style={at={(current axis.right of origin)},anchor=north west},
               y=250pt
              ]
    
    % PLOTS
    \addplot[name path=B,thick,black!10!blue] {gauss(x,\B,\Bs)};
    %\addplot[name path=S,thick,black!10!red ] {gauss(x,\S,\Ss)};
    \addplot[black,dashed,thick]
      coordinates {(\q,{-0.03*gauss(\B,\B,\Bs)}) (\q, {4.0*gauss(\q,\B,\Bs)})}
      node[below=-2pt,pos=0] {$x_\text{obs}$};
    \addplot[black,dashed,thin]
      coordinates {(\B,{-0.035*gauss(\B,\B,\Bs)}) (\B, {gauss(\B,\B,\Bs)})}
      node[below=0pt,pos=0] {$\mu$};
    \addplot[<->,black,thin]
      coordinates {(\B,{gauss(\B-\Bs,\B,\Bs)}) (\B+\Bs, {gauss(\B+\Bs,\B,\Bs)})}
      node[below,midway] {$1\sigma$};
    \addplot[<->,black,thin]
      coordinates {(\B,{2.6*gauss(\q,\B,\Bs)}) (\q,{2.6*gauss(\q,\B,\Bs)})}
      node[below,midway] {$Z\sigma$};
    
    % FILL
    \path[name path=xaxis]
      (0,0) -- (\xmax,0);
    \addplot[white!50!blue] fill between[of=xaxis and B, soft clip={domain=\q:\xmax}];
    
    % LABELS
    \node[above=2pt,  black!20!blue]    at (       \B,     {gauss(\B,\B,\Bs)}) {$\mathcal{N}(\mu,\sigma)$};
    \node[left,black!20!blue,scale=1.3] at ({0.98*\q},{0.52*gauss(\q,\B,\Bs)}) {$p$};
    
  \end{axis}
\end{tikzpicture}

\end{document}

Khi sử dụng dòng lệnh này ta sẽ render ra file ảnh PDF sau đó insert vào lại file báo cáo HTML.

library(pdftools)
library(tools)
tools::texi2dvi(file = "curve.tex", pdf = TRUE, clean = FALSE)
# knitr::include_graphics("curve.pdf")
# xfun::embed_file("curve.pdf")
pdftools::pdf_render_page("curve.pdf", dpi = 300) -> bitmap
png::writePNG(bitmap, "curve.png")
knitr::include_graphics("curve.png")

Bạn có thể insert ở dạng file PDF

Cách 3: Vẽ bell curve bằng code R

Nguồn: https://community.rstudio.com/t/right-left-skewed-normal-distribution-curve-in-r-and-shading-the-area/60251/5

library(sn)
# generating data
exposures <- seq(from = -1,
                 to = 2,
                 by = 0.01)
probabilities <- dsn(x = exposures,
                     xi = 0.1,
                     omega = 0.3,
                     alpha = 5)

# calculating measures
measures <- quantile(x = exposures,
                     probs = c(0.40, 0.60))

# plotting distribution
plot(x = exposures,
     y = probabilities,
     type = "l")

# adding vertical lines at selected measures
abline(v = c(measures[1], measures[2]))

# shading areas below arithmetic mean, above upper 0.01 point and in between
polygon(x = c(min(exposures), exposures[exposures <= measures[1]], measures[1]),
        y = c(0, probabilities[exposures <= measures[1]], 0),
        border = NA,
        col = adjustcolor(col = "red",
                          alpha.f = 0.5))
polygon(x = c(measures[1], exposures[(exposures >= measures[1]) & (exposures <= measures[2])], measures[2]),
        y = c(0, probabilities[(exposures >= measures[1]) & (exposures <= measures[2])], 0),
        border = NA,
        col = adjustcolor(col = "green",
                          alpha.f = 0.5))
polygon(x = c(measures[2], exposures[exposures >= measures[2]], max(exposures)),
        y = c(0, probabilities[exposures >= measures[2]], 0),
        border = NA,
        col = adjustcolor(col = "blue",
                          alpha.f = 0.5))

Tham khảo

  1. https://community.rstudio.com/t/loading-macros-from-external-file-into-tikz-chunks/128066
  2. https://github.com/yihui/knitr/issues/1735

Sơ kết

Trên đây là hướng dẫn vẽ TikZ trong R. Để học R bài bản từ A đến Z, thân mời Bạn tham gia khóa học “HDSD R để xử lý dữ liệu” để có nền tảng vững chắc về R nhằm tự tay làm các câu chuyện dữ liệu của riêng mình!

ĐĂNG KÝ NGAY: https://www.tuhocr.com/register