For detail, please read this article and this one.

ggplot2 parameters

library(datasauRus)
  ggplot( )+
    geom_point(data=datasaurus_dozen[datasaurus_dozen$dataset=="dino",], aes(x = x, y = y),color= "#7CAE00" ) +
    theme_void()+
    theme(legend.position = "none") 

Components of plot

  • Components of plot
    • Data: is a data frame
    • Aesthetics: is used to indicate x and y variables and to control the color, the size or the shape …
    • Geometry: the type of graphics (bar plot, line plot, scatter plot…)
  • adjust parameters
    • adjust legend using guide_
    • adjust color, size, and shape using scale_, guide_ can further adjust scale_
    • adjust panel, background, axis (font, color, size, angle), title, legend (position), caption using theme
  • types of plots
    • geom_boxplot(): Box plot
    • geom_violin(): Violin plot
    • geom_dotplot(): Dot plot
    • geom_jitter(): Jitter charts
    • geom_line(): Line plot
    • geom_bar(): Bar plot
    • geom_errorbar(): Error bars
    • geom_point(): Scatter plot
    • geom_smooth(): Add smoothed curve
    • geom_quantile(): Add quantile lines
    • geom_text(): Textual annotations
    • geom_density(): Create a smooth density curve
    • geom_histogram(): Histogram

example

data("faithful")
# Basic scatterplot
ggplot(data = faithful, 
       mapping = aes(x = eruptions, y = waiting)) + 
  geom_point()+
  stat_density_2d(aes(fill = ..level..), geom="polygon")   

# Data and mapping can be given both as global (in ggplot()) or per layer
# ggplot() + 
#   geom_point(mapping = aes(x = eruptions, y = waiting),
#              data = faithful)

Create main title, axis labels, caption

pay attention whether argument is factor or continuous.

ggplot(data = faithful, 
       mapping = aes(x = eruptions, y = waiting)) + 
  geom_point()+
  
  labs(title = "Number of xxx",
       caption = "source: http://xxx",
       x = "Eruptions" ,
       y = "Waiting time" ) +
# customize title, axis, caption  
  theme(
plot.title = element_text(color="red", size=14, face="bold.italic"),
plot.caption = element_text(color="red", size=10, face="italic"),
axis.title.x = element_text(color="blue", size=14, face="bold"),
axis.title.y = element_text(color="#993333", size=14, face="bold")
)+
  
# hide main title  
theme(plot.title = element_blank() )

Create legend title, position

p <- ggplot(faithful) + 
  geom_point(aes(x = eruptions, y = waiting, colour = eruptions < 3))+
  labs(color="Numbers of eruptions") +
  
  theme(legend.position = "left")+
# Change the appearance of legend title and labels
  theme(legend.title = element_text(colour="blue"),
          legend.text = element_text(colour="red"))+
# Change legend box background color
  theme(legend.background = element_rect(fill=NULL))
print(p)

  • customize legends using scale functions
# how to change order of legend?  
# Set legend title and labels
p+ scale_color_discrete(name = "Numbers of eruptions change", labels = c("F", "T" ))

  • customize legend

guide_colorbar(): continuous colors

guide_legend(): discrete values (shapes, colors)

ggplot(faithful) + 
  geom_point(aes(x = eruptions, y = waiting, size = eruptions < 3))+
  guides(size = guide_legend(
    # legend title
    title = "title is too low",
    title.position = "bottom",
    title.vjust = -5,
    # legend label
    label.position = "left",
    label.hjust = 1,
    label.theme = element_text(size = 15,
                               face = "italic",
                               colour = "red",
                               angle = 0),
    # label reverse
    reverse = TRUE,
    
    # width of bin
    keywidth = 1,
    
    ncol = 4
    
   )
  )
## Warning: Using size for a discrete variable is not advised.

  • delete a legend
  ggplot(mpg, aes(x = displ, y = hwy, color = class, size = cyl)) +
  geom_point() +
  guides(
    color = guide_legend("type"),      # keep
    size = "none"                      # remove
  )

  • combine two legends when they use the same variable (mapping)
  ggplot(mpg, aes(x = displ, y = hwy, color = cyl, size = cyl)) +
  geom_point() +
  scale_color_viridis_c() +
  
  guides(
    color = guide_legend("title"),
    size = guide_legend("title")
  )

# guide = "legend"

Change plot colors

set color into aes()

ggplot(faithful) + 
  geom_point(aes(x = eruptions, y = waiting, colour = eruptions < 3))

set color outside of aes()

ggplot(faithful) + 
  geom_point(aes(x = eruptions, y = waiting),
             colour = 'steelblue')

  • Colour the histogram with color and fill
ggplot(faithful) + 
  geom_histogram(aes(x = eruptions,color=eruptions < 3, fill=eruptions < 4))
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

  • Colour the histogram by waiting and changing position
ggplot(faithful) + 
  geom_histogram(aes(x = eruptions,color=waiting>60), position = 'dodge')
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

ggplot(faithful) + 
  geom_histogram(aes(x = eruptions,color=waiting>60), position = 'identity')
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

For fill and stack position, please see position section.

  • change colors manually using scale
ggplot(faithful) + 
  geom_histogram(aes(x = eruptions,color=eruptions < 3, fill=eruptions < 4))+
  # Box plot
  scale_fill_manual(values=c("#999999", "#E69F00"))

# Scatter plot
  scale_color_manual(values=c( "#E69F00", "#56B4E9"))
## <ggproto object: Class ScaleDiscrete, Scale, gg>
##     aesthetics: colour
##     axis_order: function
##     break_info: function
##     break_positions: function
##     breaks: waiver
##     call: call
##     clone: function
##     dimension: function
##     drop: TRUE
##     expand: waiver
##     get_breaks: function
##     get_breaks_minor: function
##     get_labels: function
##     get_limits: function
##     guide: legend
##     is_discrete: function
##     is_empty: function
##     labels: waiver
##     limits: NULL
##     make_sec_title: function
##     make_title: function
##     map: function
##     map_df: function
##     n.breaks.cache: NULL
##     na.translate: TRUE
##     na.value: grey50
##     name: waiver
##     palette: function
##     palette.cache: NULL
##     position: left
##     range: <ggproto object: Class RangeDiscrete, Range, gg>
##         range: NULL
##         reset: function
##         train: function
##         super:  <ggproto object: Class RangeDiscrete, Range, gg>
##     rescale: function
##     reset: function
##     scale_name: manual
##     train: function
##     train_df: function
##     transform: function
##     transform_df: function
##     super:  <ggproto object: Class ScaleDiscrete, Scale, gg>
  • using scale brewer automatically
ggplot(faithful) + 
  geom_histogram(aes(x = eruptions,color=eruptions < 3, fill=eruptions < 4))+
  # Box plot
  scale_fill_brewer(palette="Dark2")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

# Scatter plot
  scale_color_brewer(palette="Set1")
## <ggproto object: Class ScaleDiscrete, Scale, gg>
##     aesthetics: colour
##     axis_order: function
##     break_info: function
##     break_positions: function
##     breaks: waiver
##     call: call
##     clone: function
##     dimension: function
##     drop: TRUE
##     expand: waiver
##     get_breaks: function
##     get_breaks_minor: function
##     get_labels: function
##     get_limits: function
##     guide: legend
##     is_discrete: function
##     is_empty: function
##     labels: waiver
##     limits: NULL
##     make_sec_title: function
##     make_title: function
##     map: function
##     map_df: function
##     n.breaks.cache: NULL
##     na.translate: TRUE
##     na.value: NA
##     name: waiver
##     palette: function
##     palette.cache: NULL
##     position: left
##     range: <ggproto object: Class RangeDiscrete, Range, gg>
##         range: NULL
##         reset: function
##         train: function
##         super:  <ggproto object: Class RangeDiscrete, Range, gg>
##     rescale: function
##     reset: function
##     scale_name: brewer
##     train: function
##     train_df: function
##     transform: function
##     transform_df: function
##     super:  <ggproto object: Class ScaleDiscrete, Scale, gg>
  # using guide to change the color of legend key
  • using gray colors using scale
# 
p + scale_fill_grey()  #no fill element

# 
p + scale_color_grey()  

  • Gradient or continuous colors (can set the middle point aswhite)
# Color by cty values
sp2<-ggplot(mpg, aes(x = displ, y = hwy)) +
  geom_point(aes(color = cty))
sp2

# Change the low and high colors
# Sequential color scheme
sp2+scale_color_gradient(low="blue", high="red")

# Diverging color scheme
mid<-mean(mpg$cty)
sp2+scale_color_gradient2(midpoint=mid, low="blue", mid="white",
                          high="red"  )

Change points shapes, transparent and size

make the points larger and slightly transparent.

ggplot(faithful) + 
  geom_point(aes(x = eruptions, y = waiting, shape= eruptions < 3, size=eruptions), color="steelblue", alpha=0.5)

# hwo to reverse order of legend size 
ggplot(faithful) + 
  geom_point(aes(x = eruptions, y = waiting, shape= eruptions < 3, size=eruptions), color="steelblue", alpha=0.5)+

  scale_shape_manual(values=c(10, 23 ))+
 
  theme(legend.position="top")

Change bars position

p <- ggplot(mpg, aes(fl, fill = drv))

p1 <- p + geom_bar ()

p2 <- p + geom_bar(position = "dodge")
 
p3 <-p + geom_bar(position = "fill")
 
p4 <-p + geom_bar(position = "stack")

library(gridExtra)
grid.arrange(p1, p2, p3,p4, ncol=2)

Add text annotations

ggplot(data=mpg[(1:100), ], aes(x = displ, y = hwy)) +
  geom_point(aes(color = cty))+
  
  geom_text(aes(label = manufacturer ),
               size = 2, vjust = -1)  #vjust is site not direction

Add a line that (separates points)

ggplot(faithful) + 
  geom_point(aes(x = eruptions, y = waiting))+
  
  geom_abline(slope=-13,intercept = 100,color="red", linetype = "dashed")+
  # Add horizontal line at y = 2O; change line type and color
  geom_hline(yintercept=20, linetype="dotted", color = "red")+
# Add vertical line at x = 3; change line type, color and size
  geom_vline(xintercept = 3, color = "blue", size=1.5)

# Add regression line

add segment and arrow

ggplot(mpg, aes(x = displ, y = hwy )) +
  geom_point() +
# Add horizontal line segment
  geom_segment(aes(x = 2, y = 15, xend = 3, yend = 15, size=3, color="red")) +
  geom_segment(aes(x = 3, y = 33, xend = 2.5 , yend = 30),
                  arrow = arrow(length = unit(0.5, "cm")))

fitted curve

ggplot(data=mpg[mpg$fl!="c",], aes(x = displ, y = hwy)) +
  geom_point( ) +
  geom_smooth(color="red") #fitted curve
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

ggplot(data=mpg[mpg$fl!="c",], aes(x = displ, y = hwy)) +
  geom_point( ) + 
  geom_quantile() +
  geom_rug()+
  theme_minimal()
## Smoothing formula not specified. Using: y ~ x

customize line

ggplot(mpg, aes(x = displ, y = hwy, color = fl, linetype = fl, size=fl)) +
  geom_point() +
  geom_line(aes( ) )+
  labs(color="What is fl")+
  
# customize linetype, color, size  
  scale_linetype_manual(values=c("twodash", "dotted","twodash", "dotted","twodash"))+
  scale_color_manual(name = "continents",breaks = c("c", "d", "e", "Europe", "Oceania"),labels = c("africa", "americas", "asia", "europe", "oceania"),  values=c('#999999','#E69F00','#999999','#E69F00','#999999')   )+ #using breaks define three labels   
  scale_size_manual(values=seq(1,4, 0.2))+
  theme(legend.position="top") +
  
  guides(color="legend")

Using scale_ function

all mappings have associated scales even if not specified.

  • uisng scale_colour_brewer.
ggplot(mpg) + 
  geom_point(aes(x = displ, y = hwy, colour = class)) + 
  scale_colour_brewer(type = 'qual')

RColorBrewer

RColorBrewer::display.brewer.all()

  • using different palettes
ggplot(mpg) + 
  geom_point(aes(x = displ, y = hwy, colour = class)) + 
  scale_colour_brewer (palette = 'Paired')

  • showing cyl with size
ggplot(mpg) + 
  geom_point(aes(x = displ, y = hwy, colour =  class, size=cyl)) + 
  scale_colour_brewer(palette  = 'Set1' ) +
  scale_size (breaks = c(4,6))   

  • using guides to modify the scale_
 ggplot(mpg) +
   geom_point(aes(x = displ, y = hwy, colour = cyl, size=cyl)) +
   # scale_colour_brewer(palette  = 'Set1') +   #can not continuous 
   scale_size (breaks = c(4,5,6))  +
  
   guides( size = guide_legend(
            override.aes = list(color = c('red', 'blue', 'black'))))

  • unite legends

when multiple aesthetics are mapped to the same variable.

ggplot(mpg) + 
  geom_point(aes(x = displ, y = hwy, colour = cyl, size=cyl))   +
  guides(colour="legend")

category is also ok

ggplot(mpg) + 
  geom_point(aes(x = displ, y = hwy, colour = fl, size=fl))   +
  guides(colour="legend") #size is not ok
## Warning: Using size for a discrete variable is not advised.

  • x and y also have associated scales
ggplot(mpg) + 
  geom_point(aes(x = displ, y = hwy)) + 
  scale_x_continuous(breaks = c(3.5, 5, 6)) + 
  scale_y_continuous(trans = 'log2')

Change coordinates

Changing the coordinate system can have dramatic effects

  • coord_polar
ggplot(mpg) + 
  geom_bar(aes(x = class)) + 
  coord_polar()

ggplot(mpg) + 
  geom_bar(aes(x = class)) + 
  coord_polar(theta = 'y') + 
  expand_limits(y = 70)

  • specify the scale of coordinate
require(scales)
## Loading required package: scales
ggplot(mpg) + 
  geom_bar(aes(x = class)) + 
  scale_y_continuous(limits = c(0, 50), breaks = seq(0, 50, 01)) 
## Warning: Removed 1 rows containing missing values (geom_bar).

  # scale_y_continuous(labels = percent) # labels as percents
  # +
  # scale_x_discrete(labels=c(1:7)  )
  • using coord_cartesian zoom in
# have been deleted 
ggplot(mpg) + 
  geom_bar(aes(x = class)) + 
  scale_y_continuous(limits = c(0, 30))+
  scale_x_discrete( limit=c("midsize","compact"))
## Warning: Removed 146 rows containing non-finite values (stat_count).
## Warning: Removed 2 rows containing missing values (geom_bar).

ggplot(mpg) + 
  geom_bar(aes(x = class)) + 
  coord_cartesian( ylim = c(0, 30))+
  scale_x_discrete( limit=c("midsize","compact"))
## Warning: Removed 146 rows containing non-finite values (stat_count).

  • reverse direction of axes
ggplot(mpg) + 
  geom_point(aes(x = hwy, y = displ))+
  
  scale_x_continuous(breaks = c(20, 30, 35,40)) + 
  scale_y_reverse()+
  scale_y_continuous(trans="log2")
## Scale for 'y' is already present. Adding another scale for 'y', which will
## replace the existing scale.

# log10, sqrt, reverse, scale_y_continuous(trans="log2")

Customize axis ticks

  • change axis text font, color, size, angle using theme
# when use theme, scale, guide? 
ggplot(mpg) + 
  geom_point(aes(x = hwy, y = displ))+
  
  theme(axis.text.x = element_text(face="bold", color="#993333", 
                           size=14, angle=45),
          axis.text.y = element_text(face="bold", color="blue", 
                           size=7, angle=90))

  • remove aixs ticks and tick labels
ggplot(mpg) + 
  geom_point(aes(x = hwy, y = displ))+
theme(
  axis.text.x = element_blank(), # Remove x axis tick labels
  axis.text.y = element_blank(), # Remove y axis tick labels
  axis.ticks = element_blank()) # Remove ticks

Flip and reverse plot

  • boxplot and violin
ggplot(mpg ) + 
  geom_violin( aes(x = as.factor(cyl), y=hwy ,color=as.factor(cyl) ) ,trim = FALSE,width = 4 ) +
  geom_boxplot( aes(x = as.factor(cyl), y=hwy  ), notch = F , width = 0.1)  
## Warning: position_dodge requires non-overlapping x intervals

  • dotplot using stat_ function
ggplot(mpg ,aes(x = as.factor(cyl), y=hwy ) )+ 
  geom_dotplot(aes(color =as.factor(cyl), fill = as.factor(cyl)), 
                 binaxis = "y", stackdir = "center") + 
  stat_summary(fun.data="mean_sdl" )  
## Bin width defaults to 1/30 of the range of the data. Pick better value with `binwidth`.

  • errorbar
df3 <- data_summary(mpg, varname="hwy", grps= c("cyl" ))
## Loading required package: plyr
head(df3)
##   cyl      hwy       sd
## 1   4 28.80247 4.515030
## 2   5 28.75000 0.500000
## 3   6 22.82278 3.685590
## 4   8 17.62857 3.262307
ggplot( df3, aes(as.factor(cyl) ,  (hwy), ymin = hwy-sd, ymax = hwy+sd)  ) +
  geom_line(aes(group = 0 )) +
  geom_errorbar(aes(color = as.factor(cyl) ),width = 0.2) 

ggplot( df3, aes(as.factor(cyl) ,  (hwy), ymin = hwy-sd, ymax = hwy+sd)  ) +
  geom_bar(aes(fill = as.factor(cyl)), stat = "identity",
             position = "dodge") +
  geom_errorbar(aes(   ),width = 0.2) +
  coord_flip()

using original data

  ggplot(mpg, aes(cyl, hwy)) +
  stat_summary(geom = "bar") +
  stat_summary(geom = "errorbar")
## No summary function supplied, defaulting to `mean_se()`
## No summary function supplied, defaulting to `mean_se()`

flip

ggplot(mpg) + 
  geom_bar(aes(x = class)) +
  coord_flip()

reverse

ggplot(mpg) + 
  geom_bar(aes(x = class)) +
  scale_y_reverse()

Create stats

Every geom has a stat. The stat can be overwritten if we use any additional computations.

ggplot(mpg ) + 
  geom_bar (aes(x = cyl ),position = 'identity' ) #using original data

  • using transformed variables
library(dplyr)
mpg_counted <- mpg %>% 
  count(cyl, name = 'count')
head(mpg_counted)
## # A tibble: 4 × 2
##     cyl count
##   <int> <int>
## 1     4    81
## 2     5     4
## 3     6    79
## 4     8    70
ggplot(mpg_counted) + 
  geom_smooth(aes(x = cyl, y = count)) +
  geom_bar (aes(x = cyl, y = count), stat = 'identity') #using summary data 

  • using the after_stat() function inside aes().
require(scales)
ggplot(mpg) + 
  geom_bar(aes(x = class, y = after_stat(  count / sum(count))))+
  scale_y_continuous(labels = percent) # labels decimals as percents

  • using density geometric in histogram
ggplot(mpg,aes(x = hwy)) + 
  geom_histogram(aes(y=..density..))+
  geom_density(  ) 
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

  • Use stat_summary() to add the mean of hwy for each group

STAT vs. GEOM

p1 <- ggplot(mpg,aes(x = class, y = hwy) ) + 
  stat_summary(
    geom = "pointrange",
    fun.data = mean_se
  )

p2 <- ggplot(mpg,aes(x = class, y = hwy) ) + 
  stat_summary( 
  )

p3 <- ggplot(mpg,aes(x = class, y = hwy) ) + 
  stat_summary( 
  )+
  stat_summary(
    fun.data = ~mean_se(., mult = 1.96), # Increase `mult` value for bigger interval!
    geom = "errorbar",
  )

library(patchwork)
p1+p2+p3
## No summary function supplied, defaulting to `mean_se()`
## No summary function supplied, defaulting to `mean_se()`

ggplot(mpg) + 
  geom_point(aes(x = class, y = hwy), width = 0.2)+
  stat_summary(aes( x = class,y = hwy), geom="point",color="red",size=4)
## Warning: Ignoring unknown parameters: width
## No summary function supplied, defaulting to `mean_se()`

jitter points

ggplot(mpg) + 
  geom_jitter(aes(x = class, y = hwy), width = 0.2)+
  stat_summary(aes( x = class,y = hwy), geom="point",color="red",size=4)
## No summary function supplied, defaulting to `mean_se()`

Facets

facet_wrap() allows you to place facet side by side into a rectangular layout. facet_grid() allows you to specify different directions and works on two variables.

  • share the axes between the different panels
ggplot(mpg) + 
  geom_point(aes(x = displ, y = hwy)) + 
  facet_wrap(~ class)

ggplot(mpg) + 
  geom_point(aes(x = displ, y = hwy)) + 
  facet_grid(drv~ .  )

ggplot(mpg) + 
  geom_point(aes(x = displ, y = hwy)) + 
  facet_grid(~ drv  )

ggplot(mpg) + 
  geom_point(aes(x = displ, y = hwy)) + 
  facet_grid(year ~ drv)

  • do not share the axes between the different panels
ggplot(mpg) + 
  geom_point(aes(x = displ, y = hwy)) + 
  facet_wrap(~ drv , scales = "free")

only free y axes

ggplot(mpg) + 
  geom_point(aes(x = displ, y = hwy)) + 
  facet_wrap(~ drv , scales = "free_y")

  • adjust y scale (space) between the panels
ggplot(mpg) + 
  geom_bar(aes(y = manufacturer)) + 
  facet_grid(class ~ .)

ggplot(mpg) + 
  geom_bar(aes(y = manufacturer)) + 
  facet_grid(class ~ ., space = "free_y", scales = "free_y")

  • display by adding multiple variables together
ggplot(mpg) + 
  geom_point(aes(x = displ, y = hwy)) + 
  facet_wrap(year ~ drv)

Theme

theme_minimal

ggplot(mpg) + 
  geom_bar(aes(y = class)) + 
  facet_wrap(~year) + 
  theme_minimal()

Further adjustments
theme_bw

ggplot(mpg) + 
  geom_bar(aes(y = class)) + 
  facet_wrap(~year) + 
  
  labs(title = "Number of car models per class",
       caption = "source: http://fueleconomy.gov",
       x = NULL,
       y = NULL) +
   
  theme_bw() + 
  theme(
 
    strip.text = element_text(face = 'bold', hjust = 0),
    
    plot.caption = element_text(face = 'italic'),
    
    panel.grid.major = element_line('white', size = 0.5),
    panel.grid.minor = element_blank(),
    panel.grid.major.y = element_blank()
    # ,
    # panel.ontop = TRUE
  )

theme_classic

ggplot(mpg) + 
  geom_bar(aes(y = class, fill = drv)  ,position = "dodge") + 
  facet_wrap(~year) + 
  labs(title = "Number of car models per class",
       caption = "source: http://fueleconomy.gov",
       x = 'Number of cars',
       y = NULL)+
  
  scale_fill_manual(name = "Drive Models",values=c("black", "grey50",  "grey80"), labels = c("4w","Fw","Rw" )) +
  
  # scale_x_continuous(expand = c(0, NA)) + 
  
  theme_classic() + 
  theme(
    # text = element_text('Avenir Next Condensed'),
    # strip.text = element_text(face = 'bold', hjust = 0),
    
    plot.caption = element_text(face = 'italic'),
    
    panel.grid.major = element_line('white', size = 0.5),
    panel.grid.minor = element_blank(),
    panel.grid.major.y = element_blank()
    
    # panel.ontop = TRUE)
  )

  • using ggthemes
library(ggthemes)
ggplot(mpg) + 
  geom_bar(aes(y = class, fill = drv)  ,position = "dodge") + 
  facet_wrap(~year) + 
  labs(title = "Number of car models per class",
       caption = "source: http://fueleconomy.gov",
       x = 'Number of cars',
       y = NULL)+
  
  ggthemes::theme_economist()

  • customized theme
ggplot(mpg) + 
  geom_bar(aes(y = class, fill = drv)  ,position = "dodge") + 
  facet_wrap(~year) + 
  labs(title = "Number of car models per class",
       caption = "source: http://fueleconomy.gov",
       x = 'Number of cars',
       y = NULL)+
  
theme(
  
    # 1 change legend
    legend.background = element_rect(
      fill = "#fff6c2",
      color = "black",
      linetype = "dashed"
    ),
    legend.key = element_rect(fill = "grey", color = "brown"),
    legend.position = "bottom", 
    
    # 2 change panel (middle erea) background 
    panel.background = element_rect(
      fill = "#005F59",
      color = "red", size = 3
    ),
    panel.border = element_rect(
      color = "black",
      fill = "transparent",
      linetype = "dashed", size = 3
    ),
    
    # 3 change plot background
    plot.background = element_rect(
      fill = "#a1dce9",
      color = "black",
      size = 1.3
    ),
    
   
    
    # 4 change axis elements
    axis.line = element_line(color = "orange", size = 2),
    axis.title = element_text(color = "red", face = "italic"),
    axis.ticks = element_line(color = "purple", size = 3),
    axis.text = element_text(color = "blue"),
    axis.text.x = element_text(angle = 45, hjust = 1), 
    
    # 5 change facet panel
    strip.background = element_rect(fill = "orange"),
    strip.text = element_text(color = "red"),
    panel.spacing = unit(0.3, "inch") 
  )