91-R visualization 23 grob object for grid learning of underlying drawing system

  • Date : [[2022-01-05_Wed]]
  • Tags: #r / index / 02 #R/R visualization #R/R data science #R/R visualization / grid bottom drawing
  • reference resources:
    • 4.5 The grid Package | Mastering Software Development in R (bookdown.org)[1]
    • R actual combat: grid package - Happy Time - blog Park (cnblogs.com)[2]
    • (11 messages) r language grid package usage notes - viewport_ Beauty of data - CSDN blog_ R language grid package [3]

1 - basic introduction

Grid package is an underlying drawing system, which can flexibly control the appearance and layout of graphics output. However, grid package does not provide advanced drawing systems for creating complete graphics, such as ggplot2 and lattice, but provides the basic interface for drawing and developing these advanced drawings,

For example, my current business needs happen to be that the personalized customization of ggplot cannot be met, so here are some attempts. Start with a simple.

2-grob object

grob is used to control the main elements of grid drawing, including the following methods: circleglob, linesglob, polygongrob, rastergrob, rectgrob, textgrob, segmentsglob, legendgrob, xaxisgrob, and yaxisgrob

It can be seen that not only some commonly used graphic elements such as linesglob and rectGrob, but also legend legendGrob and coordinate xaxisGrob.

In addition, in addition to grid, there are other packages, including gridExtra, which can also create grob objects, such as tableGrob.

2.1 - first grob object

We can directly create the corresponding grid object through the above grob method, for example:

my_circle <- circleGrob(x = 0.5, y = 0.5, r = 0.5,
                        gp = gpar(col = "gray", lty = 3))
grid.draw(my_circle)

Unlike in ggplot, we directly assign values to graphic elements such as Col and alpha in graphic objects, or set variables through aes, set grob objects through gpar function, and assign the results to gp parameters.

Here you can review these elements: color (Col), fill (fill), transparency (alpha), line type (lty), line width (LWD), line end and join styles (lineEnd and linejoin, perspective), and font elements (fontsize, fontface, fontfamily)

In addition, drawing with grob objects requires special drawing statements, such as grid Draw or ggdraw in the cowplot package.

It is recommended to select grid only There are still some differences between the two.

2.2 - edit grob object

We can use grid Edit function to modify the grob object on the grid drawing board in real time:

my_circle <- circleGrob(name = "my_circle",x = 0.5, y = 0.5, r = 0.5,
                        gp = gpar(col = "gray", lty = 3))
grid.draw(my_circle)
my_rect <- rectGrob(x = 0.5, y = 0.5, width = 0.8, height = 0.3)
grid.draw(my_rect)
grid.edit("my_circle", gp = gpar(col = "red", lty = 1))

However, it should be noted that when creating the Grob/grid object, you need to set the name attribute and the grid Edit must be right and go through grid The operation of grid object delivered by draw to the drawing board. Otherwise, an error will be reported:

> dev.off()
> my_circle <- circleGrob(name = "my_circle",x = 0.5, y = 0.5, r = 0.5,
+                         gp = gpar(col = "gray", lty = 3))
> grid.edit("my_circle", gp = gpar(col = "red", lty = 1))
Error in editDLfromGPath(gPath, specs, strict, grep, global, redraw) : 
  non-existent'gPath'(my_circle)

In fact, ggplot object is also made based on grid system, so we can also use grid Draw to draw the ggplot object:

wc_plot <- ggplot(cars, aes(x = speed, y = dist)) + 
  geom_point()
grid.draw(wc_plot)

So, can we use grid Edit to personalize and modify the elements on ggplot? Leave a hole.

More simply, if we run the previous grid statement again, the new grid will be overwritten:

wc_plot <- ggplot(cars, aes(x = speed, y = dist)) + 
  geom_point()
grid.draw(wc_plot)
my_circle <- circleGrob(name = "my_circle",x = 0.5, y = 0.5, r = 0.5,
                        gp = gpar(col = "gray", lty = 3))
grid.draw(my_circle)

2.3 - edit ggplot object

"Bang, soon, I'll fill the hole."

However, the ggplot object is not the same as the grob declaration function. When we create it, we define the name attribute of each element. This is not only troublesome, but also unnecessary.

How can we edit them?

The combination of force + ls is mainly used here:

grid.force() # Split the grob object
grid.ls()

layout
  background.1-9-12-1
  panel.7-5-7-5
    grill.gTree.323
      panel.background..rect.314
      panel.grid.minor.y..polyline.316
      panel.grid.minor.x..polyline.318
      panel.grid.major.y..polyline.320
      panel.grid.major.x..polyline.322
    NULL
    geom_point.points.310
    NULL
    panel.border..zeroGrob.311
  spacer.8-6-8-6
  spacer.8-4-8-4
  spacer.6-6-6-6
  spacer.6-4-6-4
  axis-t.6-5-6-5
  axis-l.7-4-7-4
    NULL
    axis
      axis.1-1-1-1
        GRID.text.330
      axis.1-2-1-2
  axis-r.7-6-7-6
  axis-b.8-5-8-5
    NULL
    axis
      axis.1-1-1-1
      axis.2-1-2-1
        GRID.text.326
  xlab-t.5-5-5-5
  xlab-b.9-5-9-5
    GRID.text.334
  ylab-l.7-3-7-3
    GRID.text.337
  ylab-r.7-7-7-7
  subtitle.4-5-4-5
  title.3-5-3-5
  caption.10-5-10-5
  tag.2-2-2-2

The above is the name of each element after splitting according to the specific element. For example, the x-axis text below is grid text. Drawing point 334 is geom_point.points.310.

Let's try edit them from the following:

grid.edit("geom_point.points.310", gp = gpar(col = "red"))
grid.edit("GRID.text.334", gp = gpar(fontface = "bold"))

In addition, we can also directly convert the ggplot object into a grob object through the ggplotglob method.

2.4 - combining grob objects

In the above steps, we use grid Force, which splits the grob element of ggplot, can we combine the grob objects we created ourselves?

Here, you can use the method gTree in ggplot package to combine grob objects:

candy <- circleGrob(r = 0.1, x = 0.5, y = 0.6,
                    gp = gpar(col = "pink",
                              lty = 3,
                              lwd = 2))
stick <- segmentsGrob(x0 = 0.5, x1 = 0.5, y0 = 0, y1 = 0.5, gp = gpar(lwd = 2))
lollipop <- gTree(children = gList(candy, stick))
grid.draw(lollipop)

Use gList to pass each object to children.

So can we transform the grob object into something ggplot can manipulate?

3 - some other functions

See: R data visualization - grid system (2) - nameless article - Zhihu https://zhuanlan.zhihu.com/p/371124820

In addition to creating a grob object through the object function and then drawing through the draw statement, we can also directly specify the output and set the name through the name, such as:

grid.points(iris$Petal.Length, iris$Petal.Width, 
            name = "my_point")

reference material

[1]4.5 The grid Package | Mastering Software Development in R (bookdown.org): https://bookdown.org/rdpeng/RProgDA/the-grid-package.html#overview-of-grid-graphics

[2]R actual combat: grid package - Happy Time - blog Park (cnblogs.com): https://www.cnblogs.com/ljhdo/p/4874785.html

[3] (11 messages) r language grid package usage notes - viewport_ Beauty of data - CSDN blog_ R language grid package: https://blog.csdn.net/vivihe0/article/details/47188329

Added by Ryokotsusai on Tue, 08 Feb 2022 11:20:56 +0200