Introduction

In recent years, social media has increasingly been used to discuss protests such as Black Lives Matter, the Farmers Protest, and the recent Iran Protest. For some protests, there are also reports of internet shutdowns in response to discussing the protests online. We wanted to better understand modern protests by investigating these internet shutdowns as well as the social media discussion surrounding a protest.

Background for keepiton

In 2021, Access Now and the #KeepItOn coalition documented at least 182 internet shutdowns in 34 countries.[1]

These shutdowns have huge impact on people, communities and the global economy

Reported shutdowns

We first wanted to examine which countries had the most shutdowns over time. This animated visualization shows the number of shutdowns by country from Jan 26, 2016 to Dec 30, 2021. Each dot represents the total number of shutdowns for a country by the specific date. A red dot appears whenever a shutdown happened on a specific day during the animation. After each red dot appears, it turns gray which creates a line of gray dots that show the total number of shutdowns.

#region_total <- keep_it_on_data_n[c(1,2)]

region_total <- region_total%>% filter(start_date>  
"2010-05-01") %>%arrange((start_date))  %>% group_by(region) %>% mutate(total=row_number())
anim <- region_total %>% ggplot(aes(x = region_total$region, y= region_total$total))+
  geom_point(size=12, color = "#98041E")+
   scale_y_continuous(limits=c(1, 567), 
                      breaks = c(1,100,200,300,400,500,567))+
coord_flip()+
  ggplot2::annotate("text", x = 1.9, y = 238,size=8,color="#98041E",
           label = "From 2016-01-26 to:")+
        theme(axis.text=element_text(size=14),
              axis.title=element_text(size=20),
              plot.title=element_text(size=40))+
  labs(x= "Countries with more than 6 shutdowns", y= "Total Count", caption = paste("{frame_time}")) +
  transition_components(start_date)+
  shadow_trail(distance = 0.01, color = "#E4E4E4", size = 12)+
  #ggtitle("Reported shutdowns")+
   #theme(plot.title = element_text(size = 60, face = "bold"))+
  #shadow_mark(past = T, future=F, alpha=0.3)+
  theme(panel.background = element_blank(),
          plot.title = element_text(size=14),
         plot.caption= element_text(size=40,
                                   color="#98041E",
                                   face="bold",
                                   vjust = 14,
                                   )
    
        )


  #geom_text(aes(label = count, vjust = -50))+
animate(anim, width=800, height=700, renderer = gifski_renderer(loop = FALSE))

We can see in this visualization that India is the country with the highest number of shutdowns by a large margin.

We then wanted to examine the cause for these shutdowns.

knitr::include_graphics("actual_cause.png")

We can see that while protests are sometimes the cause of these shutdowns, there are a large variety of other causes.

The following map shows countries that have been affected by a shutdown in red.

world %>% 
  filter(admin != "Antarctica") %>%
  st_transform(crs = "+proj=robin") %>%
  ggplot()+
  geom_sf(color="darkgrey")+
  geom_sf(data=countries_off, aes(fill= "region"))+
  scale_fill_manual(values="#98041E")+
  theme_minimal()+
  theme(plot.title = element_text(face = "bold"),
        axis.text.x = element_blank(),
        legend.position = "none")+
  labs(title = "Reported Internet Shutdowns around the World",
       subtitle = "2016-01-26 ~ 2021-12-30", 
  
       
            x = NULL, y = NULL)

We can see that there is a widespread global impact of internet shutdowns.

After investigating the shutdowns dataset more broadly, we wanted to focus on a specific protest for India as it had the highest number of shutdown events. We decided to focus on the recent Farmers Protest.

Background for Farmers Protest

In September of 2020, Prime Minister Modi passed laws that allowed farmers to sell directly to buyers, which reduced the government’s role in the agricultural sector [2,3]. Farmers called for the laws to be repealed as they feared that removing government support and protections would destroy their livelihoods [2]. This resulted in a year-long series of protests by farmers in India, mostly in the states of Haryana and Punjab [2].

Here, we have an interactive map of shutdown events linked with the Farmers Protest. Click on red markers to see the event details and get the news link.

Farmers %>% 
  leaflet() %>% 
    addProviderTiles(providers$CartoDB.DarkMatter, group = "Dark") %>%
    addProviderTiles(providers$Esri.WorldTopoMap, group = "Topo") %>%
    addLayersControl(baseGroups = c("Dark", "Topo"))  %>%
    addAwesomeMarkers(icon= awesome, label = Farmers$event_details, popup =Farmers$news_link)

We can see that there were multiple shutdown events related to the Farmers Protest.

We then examined the social media response to Farmers Protest events using a dataset of English tweets tagged with #FarmersProtest[4].

Number of Tweets Over Time

We first wanted to explore the changes in the frequency of unique tweets about the protests over time.

uniquetweets <- read.csv("UniqueFarmerTweets.csv")
uniquetweets$date1 <- as.Date(uniquetweets$date1)
uniquetweets <- uniquetweets[,-1]
#pdf("FarmersTweetsOverTime_Base.pdf", width = 7, height = 4)
uniquetweets %>% 
  group_by(date1) %>% 
  summarise(Ntweets = n()) %>% 
ggplot(aes(x=date1, y=Ntweets)) +
  geom_line()+
  geom_point(alpha = 0.4, size = 1.5) +
  scale_x_date(date_breaks = "months", date_labels = "%b-%y") +
  theme_classic() +
  labs(x = "Date", y = "Number of Tweets", title = "Number of Unique English Tweets About Farmers Protest Over Time") +
  theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(angle = 45, hjust = 1), axis.title.x = element_text(size = 12), axis.title.y = element_text(size = 12))

#dev.off()

We can see that there are several spikes in number of tweets over the course of the protests. The largest spike is at the beginning of February 2021. We wanted to better understand the historical context behind these spikes (what protest events and internet shutdowns occurred on those days). Also, we wanted to investigate the tweets themselves to discover what people were saying and which sentiments they were expressing.

Context and Content for Tweets

Farmers Protest events and the corresponding content and sentiment of tweets during those events. Shutdowns and protest timeline events are from [1,3].

January 2021

Events in January 2021

knitr::include_graphics("FarmersTweetsOverTime_Jan.jpg")

Throughout January 2021, the number of tweets remained very low despite the protest events. This suggests that at this point in time, the Farmers Protest was not discussed very widely on Twitter.

February 2021

Events in early February 2021

knitr::include_graphics("FarmersTweetsOverTime_FebPart1.jpg")

Rihanna tweeted about the Farmers Protest on February 2nd [3], which resulted in increased conversation about the protests on social media and a massive spike in the number of tweets the following day. This demonstrates the influence that a public figure with a large following can have in bringing attention to global issues.

While there is a drop off in the number of tweets following the shutdown on February 6th, it is difficult to determine the direct impact of the shutdown. The dataset [4] only contains English tweets (which may originate outside of India) and these shutdowns are local to specific regions within India.

February 2, 2021

Most common words and principal sentiments for February 2, 2021

p1=ggplot(w2, aes(x = reorder(word, w), y = w)) +
  geom_col(position = "dodge",color="#1DA1F2",fill="#1DA1F2") +
  geom_text(
    aes(label = comma(w)),
    colour = "#14171A", size = 2.5,
      vjust = 0.2,hjust=-0.025)+ theme_classic()+
  theme(axis.text.x = element_text(angle = 90),
        plot.title = element_text(color="black", size=12, face="bold.italic"),
        axis.title.x = element_text(color="#14171A", size=10, face="bold"),
        axis.title.y = element_text(color="#14171A", size=10, face="bold"),
        axis.text = element_text(size = 8))+
  labs(title = "Principal words",
       x = "",
       y = "Number of tweets")+coord_flip(ylim = c(0,25000))+ scale_y_continuous(labels = comma)

p2=ggplot(sentiments1, aes(x = reorder(Sentiment, Prop), y = Prop)) +
  geom_col(position = "dodge",color="#1DA1F2",fill="#1DA1F2") +
  scale_color_manual("#1DA1F2")+
  geom_text(
    aes(label = paste0(Prop,"%")),
    colour = "#14171A", size = 2.5,
    vjust = 0.1, hjust=-0.025
  )+ theme_classic()+
  theme(axis.text.x = element_text(angle = 90),
        plot.title = element_text(color="black", size=12, face="bold.italic"),
        axis.title.x = element_text(color="#14171A", size=10, face="bold"),
        axis.title.y = element_text(color="#14171A", size=10, face="bold"),
        axis.text = element_text(size = 8))+
  labs(title = "Principal sentiments",
       x = "",
       y = "Proportion of tweets")+coord_flip(ylim = c(0,25))


#g=grid.arrange(p1, p2, ncol = 2, widths = c(0.7,0.6))
cowplot::plot_grid(p1, p2, ncol = 2, align = "h",rel_widths = c(1, 1))

##g=cowplot::plot_grid(p1, p2, ncol = 2, align = "h",rel_widths = c(1,1))
#ggsave(file="feb2_v1.jpeg", g) #saves g

February 3, 2021

Most common words and principal sentiments for February 3, 2021

p1=ggplot(w2, aes(x = reorder(word, w), y = w)) +
  geom_col(position = "dodge",color="#1DA1F2",fill="#1DA1F2") +
  geom_text(
    aes(label = comma(w)),
    colour = "#14171A", size = 2.5,
      vjust = 0.2,hjust=-0.025)+ theme_classic()+
  theme(axis.text.x = element_text(angle = 90),
        plot.title = element_text(color="black", size=12, face="bold.italic"),
        axis.title.x = element_text(color="#14171A", size=10, face="bold"),
        axis.title.y = element_text(color="#14171A", size=10, face="bold"),
        axis.text = element_text(size = 8))+
  labs(title = "Principal words",
       x = "",
       y = "Number of tweets")+coord_flip(ylim = c(0,58000))+ scale_y_continuous(labels = comma)



p2=ggplot(sentiments1, aes(x = reorder(Sentiment, Prop), y = Prop)) +
  geom_col(position = "dodge",color="#1DA1F2",fill="#1DA1F2") +
  scale_color_manual("#1DA1F2")+
  geom_text(
    aes(label = paste0(Prop,"%")),
    colour = "#14171A", size = 2.5,
    vjust = 0.1, hjust=-0.025
  )+ theme_classic()+
  theme(axis.text.x = element_text(angle = 90),
        plot.title = element_text(color="black", size=12, face="bold.italic"),
        axis.title.x = element_text(color="#14171A", size=10, face="bold"),
        axis.title.y = element_text(color="#14171A", size=10, face="bold"),
        axis.text = element_text(size = 8))+
  labs(title = "Principal sentiments",
       x = "",
       y = "Proportion of tweets")+coord_flip(ylim = c(0,28))


cowplot::plot_grid(p1, p2, ncol = 2, align = "h", rel_widths = c(1, 1))

#g=cowplot::plot_grid(p1, p2, ncol = 2, align = "h", rel_widths = c(1,1))
#ggsave(file="feb3_v1.jpeg", g) #saves g

We can see that on February 2nd and 3rd the three most used words were: farmersprotest, Rihanna, and farmers. The principal feelings were negative, positive, and fearful. A majority of the most common words on February 2nd were also the most common words on February 3rd.

It is important to highlight that on February 3rd the number of tweets exceeded 80,000 tweets, which is more than the number of tweets posted each month since the beginning of the protests.

Events in mid to late February 2021

knitr::include_graphics("FarmersTweetsOverTime_FebPart2.jpg")

On February 15th, there was a spike in tweets as people spoke out against the arrest of climate activist Disha Ravi [3].

February 15, 2021

Most common words and principal sentiments for February 15, 2021

p1=ggplot(w2, aes(x = reorder(word, w), y = w)) +
  geom_col(position = "dodge",color="#1DA1F2",fill="#1DA1F2") +
  geom_text(
    aes(label = comma(w)),
    colour = "#14171A", size = 2.5,
      vjust = 0.2,hjust=-0.025)+ theme_classic()+
  theme(axis.text.x = element_text(angle = 90),
        plot.title = element_text(color="black", size=12, face="bold.italic"),
        axis.title.x = element_text(color="#14171A", size=10, face="bold"),
        axis.title.y = element_text(color="#14171A", size=10, face="bold"),
        axis.text = element_text(size = 8))+
  labs(title = "Principal words",
       x = "",
       y = "Number of tweets")+coord_flip(ylim = c(0,5000))+ scale_y_continuous(labels = comma)


p2=ggplot(sentiments1, aes(x = reorder(Sentiment, Prop), y = Prop)) +
  geom_col(position = "dodge",color="#1DA1F2",fill="#1DA1F2") +
  scale_color_manual("#1DA1F2")+
  geom_text(
    aes(label = paste0(Prop,"%")),
    colour = "#14171A", size = 2.5,
    vjust = 0.1, hjust=-0.025
  )+ theme_classic()+
  theme(axis.text.x = element_text(angle = 90),
        plot.title = element_text(color="black", size=12, face="bold.italic"),
        axis.title.x = element_text(color="#14171A", size=10, face="bold"),
        axis.title.y = element_text(color="#14171A", size=10, face="bold"),
        axis.text = element_text(size = 8))+
  labs(title = "Principal sentiments",
       x = "",
       y = "Proportion of tweets")+coord_flip(ylim = c(0,25))

cowplot::plot_grid(p1, p2, ncol = 2, align = "h", rel_widths = c(1,1))

#g=cowplot::plot_grid(p1, p2, ncol = 2, align = "h", rel_widths = c(1,1))
#ggsave(file="feb15_v1.jpeg", g) #saves g

We can see that on February 15th the three most used words were: farmersprotest, farmers, and India. It is important to highlight that the content of the tweets shows what is happening in almost real-time with the protest. In this case, one of the most used words was Disharavi which is the name of the climate activist arrested that day. The principal feelings were negative, positive, and fearful.

July 2021

Events in July 2021

knitr::include_graphics("FarmersTweetsOverTime_Jul.jpg")

We see that there was spike on July 22nd, when there was a sit-in at a historic observatory in Dehli [3].

July 22, 2021

Most common words and principal sentiments for July 22, 2021

p1=ggplot(w2, aes(x = reorder(word, w), y = w)) +
  geom_col(position = "dodge",color="#1DA1F2",fill="#1DA1F2") +
  geom_text(
    aes(label = comma(w)),
    colour = "#14171A", size = 2.5,
      vjust = 0.2,hjust=-0.025)+ theme_classic()+
  theme(axis.text.x = element_text(angle = 90),
        plot.title = element_text(color="black", size=12, face="bold.italic"),
        axis.title.x = element_text(color="#14171A", size=10, face="bold"),
        axis.title.y = element_text(color="#14171A", size=10, face="bold"),
        axis.text = element_text(size = 8))+
  labs(title = "Principal words",
       x = "",
       y = "Number of tweets")+coord_flip(ylim = c(0,3000))+ scale_y_continuous(labels = comma)



p2=ggplot(sentiments1, aes(x = reorder(Sentiment, Prop), y = Prop)) +
  geom_col(position = "dodge",color="#1DA1F2",fill="#1DA1F2") +
  scale_color_manual("#1DA1F2")+
  geom_text(
    aes(label = paste0(Prop,"%")),
    colour = "#14171A", size = 2.5,
    vjust = 0.1, hjust=-0.025
  )+ theme_classic()+
  theme(axis.text.x = element_text(angle = 90),
        plot.title = element_text(color="black", size=12, face="bold.italic"),
        axis.title.x = element_text(color="#14171A", size=10, face="bold"),
        axis.title.y = element_text(color="#14171A", size=10, face="bold"),
        axis.text = element_text(size = 8))+
  labs(title = "Principal sentiments",
       x = "",
       y = "Proportion of tweets")+coord_flip(ylim = c(0,25))

cowplot::plot_grid(p1, p2, ncol = 2, align = "h", rel_widths = c(1,1))

#g=cowplot::plot_grid(p1, p2, ncol = 2, align = "h", rel_widths = c(1,1))
#ggsave(file="july22_v1.jpeg", g) #saves g

On July 22nd the four more common words were: support, farmers, farmersprotest, and farmersparliament. It is important to highlight that the most common words changed and now include words like economy, democracy, humanity, and parliament. This change is reflected in the sentiments because at this point there are more tweets expressing trust than fear.

September 2021

Events in September 2021

knitr::include_graphics("FarmersTweetsOverTime_Sep.jpg")

On September 5th, one of the largest demonstrations during the Farmers Protest occurred along with a spike in the number of tweets [3]. Following the demonstration, there was a shutdown on September 7th [1], which may have played a part in the subsequent dip in the number of tweets.

September 5, 2021

Most common words and principal sentiments for September 5, 2021

p1=ggplot(w2, aes(x = reorder(word, w), y = w)) +
  geom_col(position = "dodge",color="#1DA1F2",fill="#1DA1F2") +
  geom_text(
    aes(label = comma(w)),
    colour = "#14171A", size = 2.5,
      vjust = 0.2,hjust=-0.025)+ theme_classic()+
  theme(axis.text.x = element_text(angle = 90),
        plot.title = element_text(color="black", size=12, face="bold.italic"),
        axis.title.x = element_text(color="#14171A", size=10, face="bold"),
        axis.title.y = element_text(color="#14171A", size=10, face="bold"),
        axis.text = element_text(size = 8))+
  labs(title = "Principal words",
       x = "",
       y = "Number of tweets")+coord_flip(ylim = c(0,3000))+ scale_y_continuous(labels = comma)


p2=ggplot(sentiments1, aes(x = reorder(Sentiment, Prop), y = Prop)) +
  geom_col(position = "dodge",color="#1DA1F2",fill="#1DA1F2") +
  scale_color_manual("#1DA1F2")+
  geom_text(
    aes(label = paste0(Prop,"%")),
    colour = "#14171A", size = 2.5,
    vjust = 0.1, hjust=-0.025
  )+ theme_classic()+
  theme(axis.text.x = element_text(angle = 90),
        plot.title = element_text(color="black", size=12, face="bold.italic"),
        axis.title.x = element_text(color="#14171A", size=10, face="bold"),
        axis.title.y = element_text(color="#14171A", size=10, face="bold"),
        axis.text = element_text(size = 8))+
  labs(title = "Principal sentiments",
       x = "",
       y = "Proportion of tweets")+coord_flip(ylim = c(0,25))

cowplot::plot_grid(p1, p2, ncol = 2, align = "h", rel_widths = c(1,1))

#g=cowplot::plot_grid(p1, p2, ncol = 2, align = "h", rel_widths = c(1,1))
#ggsave(file="sept05_v1.jpeg", g) #saves g

On September 5th the four most used words were: farmers, farmersprotest, and Muzaffarnagar. It is important to highlight that Muzaffarnagar was the place were the farmers made their “biggest mahapanchayat” [5]. The most used words include mahapanchayat (gathering of people from around 10-12 villages), people, and laws [5]. At this point, the most common sentiment in the tweet’s content is positive.

November 2021

Events in November 2021

knitr::include_graphics("FarmersTweetsOverTime_Nov.jpg")

We see the second largest spike in the number of tweets during the Farmers Protest on November 19th, when Prime Minister Modi finally repeals the laws that the farmers have been protesting [3].

November 19, 2021

Most common words and principal sentiments for November 19, 2021

p1=ggplot(w2, aes(x = reorder(word, w), y = w)) +
  geom_col(position = "dodge",color="#1DA1F2",fill="#1DA1F2") +
  geom_text(
    aes(label = comma(w)),
    colour = "#14171A", size = 2.5,
      vjust = 0.2,hjust=-0.025)+ theme_classic()+
  theme(axis.text.x = element_text(angle = 90),
        plot.title = element_text(color="black", size=12, face="bold.italic"),
        axis.title.x = element_text(color="#14171A", size=10, face="bold"),
        axis.title.y = element_text(color="#14171A", size=10, face="bold"),
        axis.text = element_text(size = 8))+
  labs(title = "Principal words",
       x = "",
       y = "Number of tweets")+coord_flip(ylim = c(0,9000))+ scale_y_continuous(labels = comma)


p2=ggplot(sentiments1, aes(x = reorder(Sentiment, Prop), y = Prop)) +
  geom_col(position = "dodge",color="#1DA1F2",fill="#1DA1F2") +
  scale_color_manual("#1DA1F2")+
  geom_text(
    aes(label = paste0(Prop,"%")),
    colour = "#14171A", size = 2.5,
    vjust = 0.1, hjust=-0.025
  )+ theme_classic()+
  theme(axis.text.x = element_text(angle = 90),
        plot.title = element_text(color="black", size=12, face="bold.italic"),
        axis.title.x = element_text(color="#14171A", size=10, face="bold"),
        axis.title.y = element_text(color="#14171A", size=10, face="bold"),
        axis.text = element_text(size = 8))+
  labs(title = "Principal sentiments",
       x = "",
       y = "Proportion of tweets")+coord_flip(ylim = c(0,25))


cowplot::plot_grid(p1, p2, ncol = 2, align = "h", rel_widths = c(1,1))

#g=cowplot::plot_grid(p1, p2, ncol = 2, align = "h", rel_widths = c(1,1))
#ggsave(file="nov19_v1.jpeg", g) #saves g

On November 19th the four most common words were: farmersprotest, farmers, laws, and farmlaws. It is important to highlight that the most common words changed and now include victory, government, and Modi (The last name of the Prime minister). This change is reflected in the sentiments because at this point there are more tweets expressing trust than fear.

Changes in Tweet Sentiment Over Time

Change in principal sentiments over the course of the protests

knitr::include_graphics("Sentiment_AcrossTime.jpg")

During the protest, we can see how the sentiments change over time with the different actions that the government made like shutdowns, arrests, and changes in the law. Overall, the tweets’ sentiment changed from fear and anger to trust.

Conclusions

  1. In terms of shutdowns, we can see that India has the highest number of shutdowns by a large margin. For instance, all the other countries found in the keepiton dataset have at most one hundred shutdowns while India has more than five hundred.
  2. Considering how the farmers’ protest became a viral protest on Twitter because of Rihanna’s tweet, we can see how the number of followers can influence social media protests. Indeed, even when many important events happened before Rihanna’s tweet, on Twitter, the tweets related to the protest never exceeded 37 daily tweets. However, after Rihanna’s tweet, the number of tweets exceeded 80,000 number of tweets in one day.
  3. By using sentiment analysis of the content of tweets to find the most used words and the most prevalent feelings, we can see that the social media conversation reflects the protest events occurring at that time.

Limitations

One limitation we faced was that the tweet dataset that we used was only for English tweets about the Farmers Protest. Investigating tweets about the protests in other languages may reveal further insights. Another limitation was that there was no explanation in the shutdowns dataset documentation for ambiguous variable values (“unknown” and “other”).