Introduction to graphs
R is a great platform for building graphs. Literally, in a typical interactive session, you build a graph one statement at a time, adding features, until you have what you want.
The base graphic system chapter of the book, provides information on how modify and customize graphs. Two other systems, that are widely used, and provide extensive options are lattice and ggplot2. We will be mostly using the base graphic system and ggplot2.
The primary graph for a variable: the histogram
Histograms display the distribution of a continuous variable by dividing the range of scores into a specified number of bins on the x-axis and displaying the frequency of scores in each bin on the y-axis.
Basic histograms
The following chunk produces four histograms, using the R base graphic system.
#reading data on Melocactus intortus
melodata <- read.csv("melocactus.csv", header = TRUE)
#this is to produce a 2x2 graphs arrangement
par(mfrow=c(2,2))
# the most basic form
hist(melodata$alturatotal)
# controlling some aspects of the histogram
hist(melodata$alturatotal,
breaks=12,
col="green",
xlab="Altura de la planta, cm",
main="Colored histogram with 12 bins")
# with a density curve and rug plot
hist(melodata$alturatotal,
freq=FALSE,
breaks=12,
col="green",
xlab="Altura de la planta, cm",
main="Histogram, rug plot, density curve")
rug(jitter(melodata$alturatotal))
lines(density(melodata$alturatotal), col="red", lwd=2)
# including a normal curve based on the data
x <- melodata$alturatotal
h<-hist(x,
breaks=12,
col="green",
xlab="Altura de la planta, cm",
main="Histogram with normal curve and box")
xfit<-seq(min(x), max(x), length=80)
yfit<-dnorm(xfit, mean=mean(x), sd=sd(x))
yfit <- yfit*diff(h$mids[1:2])*length(x)
lines(xfit, yfit, col="red", lwd=2)
box()
Introducing ggplot2 building a histogram
Now we are going to build a histogram using ggplot2. ggplot2 provides a system for creating graphs based on the grammar of graphics. The intention of the ggplot2 package is to provide a comprehensive, grammar-based system for generating graphs in a unified and coherent manner, allowing users to create new and innovative data visualizations. The power of this approach has led ggplot2 to become an important tool for visualizing data using R.
First, let see a basic ggplot2 histogram:
melodata <- read.csv("melocactus.csv", header = TRUE)
ggplot(melodata, aes(alturatotal))+
geom_histogram(color="white", bins = 14)
Now a more detailed histogram, including several layers:
hist.melodata <- ggplot(melodata, aes(alturatotal)) +
geom_histogram(aes(y=..density..), bins = 14, colour="white", fill="green") +
geom_rug(sides = "b", color = "black") +
labs(x="Altura total de la planta,cm", y = "Density") +
stat_function(fun = dnorm,
args = list(mean = mean(melodata$alturatotal, na.rm = TRUE),
sd = sd(melodata$alturatotal, na.rm = TRUE)),
colour = "red", size = 1)
hist.melodata
The anatomy of a box-and-whiskers plot
A box-and-whiskers plot describes the distribution of a continuous variable by plotting its five-number summary: the minimum, lower quartile (25th percentile), median (50th percentile), upper quartile (75th percentile), and maximum. It can also display observations that may be outliers (values outside the range of ± 1.5*IQR, where IQR is the interquartile range defined as the upper quartile minus the lower quartile). By default, each whisker extends to the most extreme data point, which is no more than 1.5 times the interquartile range for the box. Values outside this range are depicted as dots.

Now we are going to analyze the Melocactus data using a box-plot.
ggplot(melodata, aes(x = "0", y = alturatotal)) +
geom_boxplot(fill="cornflowerblue", color="black") +
geom_point(position="jitter", size = 0.5, color="blue", alpha=.5) +
labs(x = "Melocactus intortus", y = "Altura total de la planta, cm")
Related to box-plots are the violin plots; the violin plots provide more visual cues as to the distribution of scores over the range of heights for each voice part.
ggplot(melodata, aes(x="0", y=alturatotal)) +
geom_violin(fill="lightblue") +
geom_point(color = "blue", alpha = 0.3) +
labs(x = "Melocactus intortus", y = "Altura total de la planta, cm")
Exercises
Build a graph, with the Melocactus data, that combines the box-plot and violin plot.
Bar graphs for categorical variables
Counts of cases for categorical variable are usually presented using bar graphs. Here we use data from a clinical trial of a treatment for arthritis, comparing the outcomes for treated individuals versus individuals receiving a placebo.
load("Arthr.Rdata")
head(Arthritis)
library(cowplot)
A <- ggplot(Arthritis, aes(x=Treatment, fill=Improved)) +
geom_bar(position="stack")
B <- ggplot(Arthritis, aes(x=Treatment, fill=Improved)) +
geom_bar(position="dodge")
C <- ggplot(Arthritis, aes(x=Treatment, fill=Improved)) +
geom_bar(position="fill")
#using the package cowplot to group graphs built separatelly
plot_grid(A, B, C, ncol = 2, labels = "AUTO")
Exercise
Try to improve the graphs, with smaller fonts.
LS0tCnRpdGxlOiAiRGF5X1R3byIKYXV0aG9yOiAiRC5fUy5fRmVybsOhbmRlei1kZWwtVmlzbyIKZGF0ZTogIjcvMTgvMjAxOCIKb3V0cHV0OgogIAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiA1CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAotLS0KX19TeXN0ZW0gcHJlcGFyYXRpb25fXwpgYGB7ciBzZXR1cH0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KAoJZWNobyA9IFRSVUUsCgltZXNzYWdlID0gRkFMU0UsCgl3YXJuaW5nID0gRkFMU0UKKQojIHBhY2thZ2VzIHRvIGxvYWQgKGlmIHRoZXkgYXJlIGFscmVhZHkgaW5zdGFsbGVkKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkobGF0dGljZSkKbGlicmFyeShnZ3ZlcnNhKQpgYGAKCgoKIyMjSW50cm9kdWN0aW9uIHRvIGdyYXBocwpSIGlzIGEgZ3JlYXQgcGxhdGZvcm0gZm9yIF9idWlsZGluZ18gZ3JhcGhzLiBMaXRlcmFsbHksIGluIGEgdHlwaWNhbCBpbnRlcmFjdGl2ZSBzZXNzaW9uLCB5b3UgYnVpbGQgYSBncmFwaCBvbmUgc3RhdGVtZW50IGF0IGEgdGltZSwgYWRkaW5nIGZlYXR1cmVzLCB1bnRpbCB5b3UgaGF2ZSB3aGF0IHlvdSB3YW50LiAgClRoZSBbYmFzZSBncmFwaGljIHN5c3RlbV0oaHR0cHM6Ly9saXZlYm9vay5tYW5uaW5nLmNvbSMhL2Jvb2svci1pbi1hY3Rpb24tc2Vjb25kLWVkaXRpb24vY2hhcHRlci0zL3BvaW50LTI3ODMtMTAtMTQtMCkgY2hhcHRlciBvZiB0aGUgYm9vaywgcHJvdmlkZXMgaW5mb3JtYXRpb24gb24gaG93IG1vZGlmeSBhbmQgY3VzdG9taXplIGdyYXBocy4KVHdvIG90aGVyIHN5c3RlbXMsIHRoYXQgYXJlIHdpZGVseSB1c2VkLCBhbmQgcHJvdmlkZSBleHRlbnNpdmUgb3B0aW9ucyBhcmUgW19fbGF0dGljZV9fXSh3d3cuc3RhdG1ldGhvZHMubmV0L1JpQS9sYXR0aWNlLnBkZikgYW5kIFtfX2dncGxvdDJfX10oaHR0cHM6Ly9saXZlYm9vay5tYW5uaW5nLmNvbSMhL2Jvb2svci1pbi1hY3Rpb24tc2Vjb25kLWVkaXRpb24vY2hhcHRlci0xOS9wb2ludC0yNzg0LTEtNS0wKS4gIFdlIHdpbGwgYmUgbW9zdGx5IHVzaW5nIHRoZSBiYXNlIGdyYXBoaWMgc3lzdGVtIGFuZCBnZ3Bsb3QyLgoKIyMjI1RoZSBwcmltYXJ5IGdyYXBoIGZvciBhIHZhcmlhYmxlOiB0aGUgaGlzdG9ncmFtCkhpc3RvZ3JhbXMgZGlzcGxheSB0aGUgZGlzdHJpYnV0aW9uIG9mIGEgY29udGludW91cyB2YXJpYWJsZSBieSBkaXZpZGluZyB0aGUgcmFuZ2Ugb2Ygc2NvcmVzIGludG8gYSBzcGVjaWZpZWQgbnVtYmVyIG9mIGJpbnMgb24gdGhlIHgtYXhpcyBhbmQgZGlzcGxheWluZyB0aGUgZnJlcXVlbmN5IG9mIHNjb3JlcyBpbiBlYWNoIGJpbiBvbiB0aGUgeS1heGlzLiAKCiMjIyMjQmFzaWMgaGlzdG9ncmFtcwpUaGUgZm9sbG93aW5nIGNodW5rIHByb2R1Y2VzIGZvdXIgaGlzdG9ncmFtcywgdXNpbmcgdGhlIFIgYmFzZSBncmFwaGljIHN5c3RlbS4gCmBgYHtyIGJhc2ljX2hpc3RvZ3JhbSwgZWNobz1UUlVFfQojcmVhZGluZyBkYXRhIG9uIE1lbG9jYWN0dXMgaW50b3J0dXMKbWVsb2RhdGEgPC0gcmVhZC5jc3YoIm1lbG9jYWN0dXMuY3N2IiwgaGVhZGVyID0gVFJVRSkKI3RoaXMgaXMgdG8gcHJvZHVjZSBhIDJ4MiBncmFwaHMgYXJyYW5nZW1lbnQKcGFyKG1mcm93PWMoMiwyKSkKIyB0aGUgbW9zdCBiYXNpYyBmb3JtCmhpc3QobWVsb2RhdGEkYWx0dXJhdG90YWwpCQoKIyBjb250cm9sbGluZyBzb21lIGFzcGVjdHMgb2YgdGhlIGhpc3RvZ3JhbQpoaXN0KG1lbG9kYXRhJGFsdHVyYXRvdGFsLAogICAgIGJyZWFrcz0xMiwKICAgICBjb2w9ImdyZWVuIiwKICAgICB4bGFiPSJBbHR1cmEgZGUgbGEgcGxhbnRhLCBjbSIsCiAgICAgbWFpbj0iQ29sb3JlZCBoaXN0b2dyYW0gd2l0aCAxMiBiaW5zIikKCiMgd2l0aCBhIGRlbnNpdHkgY3VydmUgYW5kIHJ1ZyBwbG90IApoaXN0KG1lbG9kYXRhJGFsdHVyYXRvdGFsLAogICAgIGZyZXE9RkFMU0UsCiAgICAgYnJlYWtzPTEyLAogICAgIGNvbD0iZ3JlZW4iLAogICAgIHhsYWI9IkFsdHVyYSBkZSBsYSBwbGFudGEsIGNtIiwKICAgICBtYWluPSJIaXN0b2dyYW0sIHJ1ZyBwbG90LCBkZW5zaXR5IGN1cnZlIikKcnVnKGppdHRlcihtZWxvZGF0YSRhbHR1cmF0b3RhbCkpCmxpbmVzKGRlbnNpdHkobWVsb2RhdGEkYWx0dXJhdG90YWwpLCBjb2w9InJlZCIsIGx3ZD0yKQoKIyBpbmNsdWRpbmcgYSBub3JtYWwgY3VydmUgYmFzZWQgb24gdGhlIGRhdGEKeCA8LSBtZWxvZGF0YSRhbHR1cmF0b3RhbApoPC1oaXN0KHgsCiAgICAgICAgYnJlYWtzPTEyLAogICAgICAgIGNvbD0iZ3JlZW4iLAogICAgICAgIHhsYWI9IkFsdHVyYSBkZSBsYSBwbGFudGEsIGNtIiwKICAgICAgICBtYWluPSJIaXN0b2dyYW0gd2l0aCBub3JtYWwgY3VydmUgYW5kIGJveCIpCnhmaXQ8LXNlcShtaW4oeCksIG1heCh4KSwgbGVuZ3RoPTgwKQp5Zml0PC1kbm9ybSh4Zml0LCBtZWFuPW1lYW4oeCksIHNkPXNkKHgpKQp5Zml0IDwtIHlmaXQqZGlmZihoJG1pZHNbMToyXSkqbGVuZ3RoKHgpCmxpbmVzKHhmaXQsIHlmaXQsIGNvbD0icmVkIiwgbHdkPTIpCmJveCgpCmBgYAoKIyMjIyNJbnRyb2R1Y2luZyBnZ3Bsb3QyIGJ1aWxkaW5nIGEgaGlzdG9ncmFtCk5vdyB3ZSBhcmUgZ29pbmcgdG8gYnVpbGQgYSBoaXN0b2dyYW0gdXNpbmcgZ2dwbG90Mi4gIFtnZ3Bsb3QyXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZ2dwbG90Mi9nZ3Bsb3QyLnBkZikgcHJvdmlkZXMgYSBzeXN0ZW0gZm9yIGNyZWF0aW5nIGdyYXBocyBiYXNlZCBvbiB0aGUgZ3JhbW1hciBvZiBncmFwaGljcy4gVGhlIGludGVudGlvbiBvZiB0aGUgZ2dwbG90MiBwYWNrYWdlIGlzIHRvIHByb3ZpZGUgYSBjb21wcmVoZW5zaXZlLCBncmFtbWFyLWJhc2VkIHN5c3RlbSBmb3IgZ2VuZXJhdGluZyBncmFwaHMgaW4gYSB1bmlmaWVkIGFuZCBjb2hlcmVudCBtYW5uZXIsIGFsbG93aW5nIHVzZXJzIHRvIGNyZWF0ZSBuZXcgYW5kIGlubm92YXRpdmUgZGF0YSB2aXN1YWxpemF0aW9ucy4gVGhlIHBvd2VyIG9mIHRoaXMgYXBwcm9hY2ggaGFzIGxlZCBnZ3Bsb3QyIHRvIGJlY29tZSBhbiBpbXBvcnRhbnQgdG9vbCBmb3IgdmlzdWFsaXppbmcgZGF0YSB1c2luZyBSLgoKRmlyc3QsIGxldCBzZWUgYSBiYXNpYyBnZ3Bsb3QyIGhpc3RvZ3JhbToKYGBge3IgZ2dwbG90Ml9oaXN0b19iYXNpYywgZWNobz1UUlVFLCBtZXNzYWdlPVRSVUUsIHBhZ2VkLnByaW50PVRSVUV9Cm1lbG9kYXRhIDwtIHJlYWQuY3N2KCJtZWxvY2FjdHVzLmNzdiIsIGhlYWRlciA9IFRSVUUpCgpnZ3Bsb3QobWVsb2RhdGEsIGFlcyhhbHR1cmF0b3RhbCkpKwogIGdlb21faGlzdG9ncmFtKGNvbG9yPSJ3aGl0ZSIsIGJpbnMgPSAxNCkKYGBgCgpOb3cgYSBtb3JlIGRldGFpbGVkIGhpc3RvZ3JhbSwgaW5jbHVkaW5nIHNldmVyYWwgX2xheWVyc186CmBgYHtyIGdncGxvdDJfaGlzdG9fZnVsbH0KaGlzdC5tZWxvZGF0YSA8LSBnZ3Bsb3QobWVsb2RhdGEsIGFlcyhhbHR1cmF0b3RhbCkpICsgCiAgZ2VvbV9oaXN0b2dyYW0oYWVzKHk9Li5kZW5zaXR5Li4pLCBiaW5zID0gMTQsIGNvbG91cj0id2hpdGUiLCBmaWxsPSJncmVlbiIpICsKICBnZW9tX3J1ZyhzaWRlcyA9ICJiIiwgY29sb3IgPSAiYmxhY2siKSArCiAgbGFicyh4PSJBbHR1cmEgdG90YWwgZGUgbGEgcGxhbnRhLGNtIiwgeSA9ICJEZW5zaXR5IikgKwogIHN0YXRfZnVuY3Rpb24oZnVuID0gZG5vcm0sIAogICAgICAgICAgICAgICAgYXJncyA9IGxpc3QobWVhbiA9IG1lYW4obWVsb2RhdGEkYWx0dXJhdG90YWwsIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2QgPSBzZChtZWxvZGF0YSRhbHR1cmF0b3RhbCwgbmEucm0gPSBUUlVFKSksIAogICAgICAgICAgICAgICAgY29sb3VyID0gInJlZCIsIHNpemUgPSAxKQpoaXN0Lm1lbG9kYXRhCmBgYAoKIyMjI1RoZSBhbmF0b215IG9mIGEgYm94LWFuZC13aGlza2VycyBwbG90CkEgW2JveC1hbmQtd2hpc2tlcnMgcGxvdF0oaHR0cHM6Ly9saXZlYm9vay5tYW5uaW5nLmNvbSMhL2Jvb2svci1pbi1hY3Rpb24tc2Vjb25kLWVkaXRpb24vY2hhcHRlci02L3BvaW50LTI3ODUtMTAxLTEwMi0wKSBkZXNjcmliZXMgdGhlIGRpc3RyaWJ1dGlvbiBvZiBhIGNvbnRpbnVvdXMgdmFyaWFibGUgYnkgcGxvdHRpbmcgaXRzIGZpdmUtbnVtYmVyIHN1bW1hcnk6IHRoZSBtaW5pbXVtLCBsb3dlciBxdWFydGlsZSAoMjV0aCBwZXJjZW50aWxlKSwgbWVkaWFuICg1MHRoIHBlcmNlbnRpbGUpLCB1cHBlciBxdWFydGlsZSAoNzV0aCBwZXJjZW50aWxlKSwgYW5kIG1heGltdW0uIEl0IGNhbiBhbHNvIGRpc3BsYXkgb2JzZXJ2YXRpb25zIHRoYXQgbWF5IGJlIG91dGxpZXJzICh2YWx1ZXMgb3V0c2lkZSB0aGUgcmFuZ2Ugb2YgwrEgMS41KklRUiwgd2hlcmUgSVFSIGlzIHRoZSBpbnRlcnF1YXJ0aWxlIHJhbmdlIGRlZmluZWQgYXMgdGhlIHVwcGVyIHF1YXJ0aWxlIG1pbnVzIHRoZSBsb3dlciBxdWFydGlsZSkuIEJ5IGRlZmF1bHQsIGVhY2ggd2hpc2tlciBleHRlbmRzIHRvIHRoZSBtb3N0IGV4dHJlbWUgZGF0YSBwb2ludCwgd2hpY2ggaXMgbm8gbW9yZSB0aGFuIDEuNSB0aW1lcyB0aGUgaW50ZXJxdWFydGlsZSByYW5nZSBmb3IgdGhlIGJveC4gVmFsdWVzIG91dHNpZGUgdGhpcyByYW5nZSBhcmUgZGVwaWN0ZWQgYXMgZG90cy4KCj4hW10oYm94cGxvdC5qcGcpeyNpZCAuY2xhc3Mgd2lkdGg9MzYwIGhlaWdodD0yNDBweH1cCgpOb3cgd2UgYXJlIGdvaW5nIHRvIGFuYWx5emUgdGhlIF9NZWxvY2FjdHVzXyBkYXRhIHVzaW5nIGEgYm94LXBsb3QuCmBgYHtyIGdncGxvdDJfYm94cGxvdH0KZ2dwbG90KG1lbG9kYXRhLCBhZXMoeCA9ICIwIiwgeSA9IGFsdHVyYXRvdGFsKSkgKwogIGdlb21fYm94cGxvdChmaWxsPSJjb3JuZmxvd2VyYmx1ZSIsIGNvbG9yPSJibGFjayIpICsKICBnZW9tX3BvaW50KHBvc2l0aW9uPSJqaXR0ZXIiLCBzaXplID0gMC41LCBjb2xvcj0iYmx1ZSIsIGFscGhhPS41KSArCiAgbGFicyh4ID0gIk1lbG9jYWN0dXMgaW50b3J0dXMiLCB5ID0gIkFsdHVyYSB0b3RhbCBkZSBsYSBwbGFudGEsIGNtIikKYGBgCgpSZWxhdGVkIHRvIGJveC1wbG90cyBhcmUgdGhlIFt2aW9saW4gcGxvdHNdKGh0dHBzOi8vbGl2ZWJvb2subWFubmluZy5jb20jIS9ib29rL3ItaW4tYWN0aW9uLXNlY29uZC1lZGl0aW9uL2NoYXB0ZXItMTkvcG9pbnQtMjc4Ni02Mi02NC0wKTsgdGhlIHZpb2xpbiBwbG90cyBwcm92aWRlIG1vcmUgdmlzdWFsIGN1ZXMgYXMgdG8gdGhlIGRpc3RyaWJ1dGlvbiBvZiBzY29yZXMgb3ZlciB0aGUgcmFuZ2Ugb2YgaGVpZ2h0cyBmb3IgZWFjaCB2b2ljZSBwYXJ0LgpgYGB7ciBnZ3Bsb3QyX3Zpb2xpbn0KZ2dwbG90KG1lbG9kYXRhLCBhZXMoeD0iMCIsIHk9YWx0dXJhdG90YWwpKSArCiAgZ2VvbV92aW9saW4oZmlsbD0ibGlnaHRibHVlIikgKwogIGdlb21fcG9pbnQoY29sb3IgPSAiYmx1ZSIsIGFscGhhID0gMC4zKSArCiAgbGFicyh4ID0gIk1lbG9jYWN0dXMgaW50b3J0dXMiLCB5ID0gIkFsdHVyYSB0b3RhbCBkZSBsYSBwbGFudGEsIGNtIikKYGBgCgojIyMjX0V4ZXJjaXNlc18KQnVpbGQgYSBncmFwaCwgd2l0aCB0aGUgTWVsb2NhY3R1cyBkYXRhLCB0aGF0IGNvbWJpbmVzIHRoZSBib3gtcGxvdCBhbmQgdmlvbGluIHBsb3QuCgojIyMjQmFyIGdyYXBocyBmb3IgY2F0ZWdvcmljYWwgdmFyaWFibGVzCkNvdW50cyBvZiBjYXNlcyBmb3IgY2F0ZWdvcmljYWwgdmFyaWFibGUgYXJlIHVzdWFsbHkgcHJlc2VudGVkIHVzaW5nIGJhciBncmFwaHMuICBIZXJlIHdlIHVzZSBkYXRhIGZyb20gYSBjbGluaWNhbCB0cmlhbCBvZiBhIHRyZWF0bWVudCBmb3IgYXJ0aHJpdGlzLCBjb21wYXJpbmcgdGhlIG91dGNvbWVzIGZvciB0cmVhdGVkIGluZGl2aWR1YWxzIF92ZXJzdXNfIGluZGl2aWR1YWxzIHJlY2VpdmluZyBhIHBsYWNlYm8uIApgYGB7ciB9CmxvYWQoIkFydGhyLlJkYXRhIikKaGVhZChBcnRocml0aXMpCmxpYnJhcnkoY293cGxvdCkKQSA8LSBnZ3Bsb3QoQXJ0aHJpdGlzLCBhZXMoeD1UcmVhdG1lbnQsIGZpbGw9SW1wcm92ZWQpKSArCiAgICAgZ2VvbV9iYXIocG9zaXRpb249InN0YWNrIikKQiA8LSBnZ3Bsb3QoQXJ0aHJpdGlzLCBhZXMoeD1UcmVhdG1lbnQsIGZpbGw9SW1wcm92ZWQpKSArCiAgICAgZ2VvbV9iYXIocG9zaXRpb249ImRvZGdlIikKQyA8LSBnZ3Bsb3QoQXJ0aHJpdGlzLCBhZXMoeD1UcmVhdG1lbnQsIGZpbGw9SW1wcm92ZWQpKSArCiAgICAgZ2VvbV9iYXIocG9zaXRpb249ImZpbGwiKQojdXNpbmcgdGhlIHBhY2thZ2UgY293cGxvdCB0byBncm91cCBncmFwaHMgYnVpbHQgc2VwYXJhdGVsbHkKcGxvdF9ncmlkKEEsIEIsIEMsIG5jb2wgPSAyLCBsYWJlbHMgPSAiQVVUTyIpCmBgYAoKIyMjI19FeGVyY2lzZV8KVHJ5IHRvIGltcHJvdmUgdGhlIGdyYXBocywgd2l0aCBzbWFsbGVyIGZvbnRzLgoKKioqCgojIyNTdGF0aXN0aWNhbCB0ZXN0cyBhbmQgZ3JhcGhzIGZvciB0d28gb3IgbW9yZSB2YXJpYWJsZXMKSW4gdGhpcyBzZWN0aW9uIHdlIHdpbGwgY29uc2lkZXIgdGhlIHRlc3Rpbmcgb2Ygc3RhdGlzdGljYWwgaHlwb3RoZXNpcyBmb3IgdHdvIG9yIG1vcmUgdmFyaWFibGVzLCBhbmQgdGhlIGdyYXBocyB0aGF0IHdpbGwgaGVscCBpbiB0aGUgaW50ZXJwcmV0YXRpb24gb2YgdGhlIHJlc3VsdHMuIAojIyMjUmVncmVzc2lvbiBhbmFseXNpcwoKIyMjI0FOT1ZBCgoK