Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to plot individual components in horizontal bar chart?

Tags:

r

ggplot2

I am trying to analyse soccer data, where particular passes and goals are tracked over 3 periods of play or Term. The type of defensive structure or Mode employed by one team is also tracked. An example of my dataset is below:

# Example data
Time <- c(1, 1, 2, 3, 4, 5, 6, 9, 1, 2, 3, 5, 5, 7, 9, 1, 2, 4, 7, 9)
Event <- c("Pass", "Pass", "Pass", "Goal", "Pass", "Pass", "Goal", "Pass", "Pass", 
           "Pass", "Pass", "Pass", "Pass", "Pass", "Pass", "Goal", "Pass", "Pass", "Pass", "Goal")
Term <- c(1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3) 
Symbol <- c("P", "P", "P", "G", "P", "P", "G", "P", "P", 
            "P", "P", "P", "P", "P", "P", "G", "P", "P", "P", "G")
By <- c("Home", "Away", "Home", "Home", "Home", "Away", "Away", "Away", "Home", 
            "Home", "Home", "Away", "Away", "Away", "Home", "Home", "Home", "Away", "Away", "Away")
Mode <- c("Press", "Press", "Press", "Forward", "Forward", "Forward", "Forward", "Press", "Press", 
            "Press", "Press", "Press", "Press", "Forward", "Forward", "Forward", "Forward", "Press", "Press", "Forward")
# Make data.frame
GameData <- data.frame(Time, Event, Term, Symbol, By, Mode)
# Make factors
GameData$Event <- as.factor(GameData$Event)
GameData$Symbol <- as.factor(GameData$Symbol)
GameData$Mode <- as.factor(GameData$Mode)
GameData$Term <- as.factor(GameData$Term)
GameData$By <- as.factor(GameData$By)

I want to visualise when these passes and goals are performed over Time, according to when the Mode is changed. However, when I plot this as a horizontal bar figure in ggplot2, the time is instead summed rather than colour changing at the appropriate time. For example, the maximum time for each term is 9 minutes but the x-axis goes up to 30? My code for the plot is below:

# Load package
require(ggplot2)
# Plot
ggplot(GameData, aes(x = Term, y = Time, fill = Mode)) +
  geom_bar(stat = "identity") +
  geom_text(data = GameData, aes(label = Symbol, colour = By), size = 9) +
  scale_color_manual(values =c("black", "red")) +
  coord_flip() +
  scale_x_discrete(limits = rev(levels(GameData$Term))) 

I feel like this is a silly mistake but where am I going wrong, so the colour/ Mode changes at the corresponding time?

In summary, I want the background of the plot below to have a different colour for each Mode over Time for each Term.

# Plot
ggplot(GameData, aes(x = Term, y = Time, fill = Mode)) +
  geom_text(data = GameData, aes(label = Symbol, colour = By), size = 9) +
  scale_color_manual(values =c("black", "red")) +
  coord_flip() +
  scale_x_discrete(limits = rev(levels(GameData$Term))) +
  theme_classic()

Thanks.

like image 925
user2716568 Avatar asked Dec 11 '25 21:12

user2716568


1 Answers

Here is a partial solution using geom_tile() to draw the colored bars (Thanks to @Gregor for the idea).

# Work around to make sure Time=8 appears on x-axis.
GameData$discrete_time = factor(GameData$Time, levels=paste(1:9))

plot1 = ggplot(GameData, aes(y=Term, x=discrete_time)) +
        geom_tile(aes(fill=Mode)) +
        geom_text(aes(label=Symbol, colour=By), size=9) +
        scale_color_manual(values=c("black", "white")) +
        scale_fill_brewer(palette="Set1") +
        scale_x_discrete(drop=FALSE)

ggsave("plot.png", plot=plot1, width=9, height=3, dpi=150)

enter image description here


Comments:

  • You can fill in the empty tiles by adding appropriate rows to your data (set Symbol to NA to color the tile but leave Pass/Goal blank).
  • There are some locations (Term=1, Time=1, for example) where there are two 'Passes' that are fully overlapping. I tried various dodging, jittering, grouping strategies but nothing looked good and revealed the overlapping events. Solving this issue will become more important if you scale up to larger datasets.
like image 141
bdemarest Avatar answered Dec 14 '25 11:12

bdemarest



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!