-
Notifications
You must be signed in to change notification settings - Fork 39
/
ggplot2_mel.Rmd
700 lines (415 loc) · 22.6 KB
/
ggplot2_mel.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
---
output: html_document
editor_options:
chunk_output_type: console
---
# Visualizing: `ggplot2` {#ggplot2}
```{r viz ops, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, warning = F, message = F)
library(htmltools)
```
## Why ggplot2?
This tutorial focuses exclusively on data visualization using ggplot2 because this package:
* provides a coherent language for visualizing data (vs. the original 'plot' function, which developed in an ad-hoc way)
* makes many tasks easier, such as: visualizing a third (z) variable; saving figures; automating plotting and formatting tasks
* creates beautiful figures and is flexible
You should really use ggplot2 for nearly all data visualization!
## Additional resources for data visualization in R
The goal of this tutorial is to introduce you to the basics of ggplot2. I focus only on the features I use most often. We will barely scratch the surface of ggplot2's functionality. But there are many resources that will help you learn more. Here are some of the ones I use:
- The official ggplot2 [cheatsheet](https://www.rstudio.com/wp-content/uploads/2015/03/ggplot2-cheatsheet.pdf) is amazing!
- Winston Chang's book converted me from someone who was slightly confused by ggplot2 to a superuser....so I can't recommend it enough! And, the [associated website](http://www.cookbook-r.com/Graphs/#graphs-with-ggplot2) is great too.
<br>
![](img/ChangBook.png)
<br>
- Hadley Wickham's [R for Data Science book](http://r4ds.had.co.nz/data-visualisation.html), which is inspiration for much of this tutorial.
## Objectives
- install the `ggplot2` package by installing `tidyverse`
- learn basics of ggplot2 with a dataset describing global ocean health
- practice writing a script in RMarkdown
- practice the rstudio-github workflow
## Install tidyverse: `tidyverse`
We will use the `ggplot2` package, which is bundled with a composite-package called `tidyverse`. Check out [tidyverse.org/](https://www.tidyverse.org) for more information.
We will download and install `tidyverse`:
```{r, eval=FALSE, messages=FALSE}
## from CRAN:
install.packages("tidyverse") ## do this once only to install the package on your computer.
```
You will see some messages describing which packages were installed with `tidyverse`. Messages about name conflicts are also returned. This is not a problem its just an alert that two functions from dplyr will replace functions in the built-in stats package with the same name.
## Create an RMarkdown file to work from
---
**To do:**
**Create a new R Markdown file**
We will create the RMarkdown file you will be working from. You can write notes to yourself in Markdown and have a record of all your R code.
Go to File > New File > R Markdown ... (or click the green plus in the top left corner).
Next, replace all the automatic text with the following:
```
---
title: "Graphics with ggplot2"
author: "Julie"
date: "11/21/2017"
output: html_document
---
# Learning ggplot2
We're learning ggplot2 It's going to be amazing.
```
Now, let's save the file. I'm going to call my file `ggplot2.Rmd`. Do a *pull*...then *stage/commit* (to save to git history)...then *push* to sync with GitHub.com.
---
## Load the tidverse
We have downloaded the tidyverse package but it is not yet loaded in the R workspace. We will use the `library()` function to load tidyverse. This will be the first code chunk in your RMarkdown:
```{r, messages = FALSE}
library(tidyverse) ## do this every time you restart R and need it
```
## Load and explore data
We will load the dataset we will be using for this tutorial into our workspace directly from GitHub.com (I always find this GitHub functionality so cool!).
```{r load_data}
ohi_data <- read_csv("https://raw.githubusercontent.com/OHI-Science/data-science-training/master/data/OHI_global_data.csv")
```
These data are from the global [Ocean Health Index](http://ohi-science.org/ohi-global/) which assesses the condition of marine resources for 220 countries or territories.
The dataset includes:
variable | description | data type | examples
-- | ------------------------- | -- | ----------------------------
country | OHI region name for country or territorial regions with marine coastline | character | Jarvis Island, Italy
OHI_score | Ocean Health Index scores describing condition of marine resources based on the 2017 global assessment | numeric | values can range from 0-100, with 100 being the best possible score
OHI_trend | average annual change in OHI scores from 2012 to 2017 | numeric | values range from -3.9 to 1.86, with positive values indicating improving scores
coastal_pop | human population within 25 miles of coast | numeric | values range from 0 to >317 million
log_coastal_pop | log(coastal_pop + 1) | numeric | values range from 0 to ~20
cumulative_human_impact | average cumulative impact of human stressors (e.g., SST, shipping, pollution) on marine ecosystems within the country's marine boundaries | numeric | values range from 1.419 to 6.762, with larger values indicating higher impact
HDI | [Human Development Index](http://hdr.undp.org/en/content/human-development-index-hdi) scores, which measure average achievement in key dimensions of human development: a long and healthy life, being knowledgeable and have a decent standard of living. | numeric | values are rescaled to be between 0 to 1, with higher scores indicating better human development
georegion_one | lower resolution UN georegion designations based on georegional and social similarities | character | Africa, Americas, Asia
georegion_two | higher resolution UN georegion designations based on georegional and social similarities | character | Australia and New Zealand, Eastern Asia, Caribbean
<br>
Let's explore these data, shall we:
```{r explore_data}
head(ohi_data)
summary(ohi_data)
table(ohi_data$georegion_one)
table(ohi_data$georegion_two)
```
## Plotting with **`ggplot2`**
Plots are created using a step-wise approach that is flexible and easily customized. We will walk through the steps needed to build a plot in ggplot2.
*HINT: Start with the simplest version of your plot and build onto it.*
### Step 1: Identify the dataframe
ggplot2 requires the data to be in a dataframe format. The first step is to use the `ggplot()` function to identify the dataframe with the data you want to plot.
At this point, we will also assign the x and y axis variables within the aes function (this stands for aesthetics, and we will discuss this concept after we have a plot to work with).
[NOTE: This step was confusing for me for a long time because it doesn't actually make the plot!]
```{r, eval=FALSE}
ggplot(data = ohi_data, aes(x = OHI_score, y = HDI))
```
### Step 2: Identify the style of plot you want to create (i.e., the geom)
Next, we will actually create the plot by adding a geom function using the `+` operator.
A __geom__ is the geometrical object that a plot uses to represent data. For example, bar charts use bar geoms, line charts use line geoms, boxplots use boxplot geoms, and so on.
You can use different geoms to plot the same data. To change the type of plot, change the geom function that you add to `ggplot()`.
`ggplot2` provides over 30 geoms, which are described in the official ggplot2 [cheatsheet](https://www.rstudio.com/wp-content/uploads/2015/03/ggplot2-cheatsheet.pdf). To learn more about any single geom, use help: `?geom_smooth`. Extension packages provide even more geoms (see <https://www.ggplot2-exts.org> for a sampling).
We will start by creating a scatterplot of ohi scores within UN georegions by adding the `geom_point` function.
```{r first-ggplot}
ggplot(data = ohi_data, aes(x = georegion_one, y =OHI_score)) +
geom_point()
```
Yay! A plot!
Next we will replace geom_point() with geom_jitter() to create a style of plot with the same data. geom_jitter is similar to geom_point, but it adds random variation to values along the x-axis to separate points:
```{r second-ggplot}
ggplot(data = ohi_data, aes(x = georegion_one, y =OHI_score)) +
geom_jitter(width=0.2) # the width argument describes how much scatter to add
```
<br>
Now we will explore other geoms.
The following bar plot uses geom_bar to describe the number of countries in each UN category:
```{r barplot2}
ggplot(data = ohi_data, aes(x = georegion_one)) +
geom_bar()
```
<br>
A histogram using geom_histogram:
```{r histogram}
ggplot(data = ohi_data, aes(x = HDI)) +
geom_histogram()
```
<br>
Multiple geoms can be layered on the same plot. Geom layers can be added using either the same or different dataframes. To demonstrate this we will use a secondary dataset with the mean OHI score for each UN georegion. We will create a bar plot of the means for each region and then overlay the point data.
```{r third-ggplot}
ohi_summary <- read_csv("https://raw.githubusercontent.com/OHI-Science/data-science-training/master/data/OHI_scores_georegion_summary.csv")
ohi_summary
ggplot(data = ohi_summary, aes(x = georegions, y = OHI_score_average)) +
geom_bar(stat="identity") +
geom_jitter(data=ohi_data, aes(x=georegion_one, y=OHI_score))
```
<br>
In the above example, the global mappings are designated by: `ggplot(data = ohi_summary, aes(x = georegions, y = OHI_score_average))`. These are then overwritten by the local mappings designated in the geom_jitter layer. The global designations will apply to subsequent layers, unless otherwise changed. This makes it possible to display different aesthetics and data in different layers.
<br>
<br>
---
> **STOP: let's Commit, Pull and Push to GitHub**
**And discuss the following**
1. In the code below, why isn't the data showing up?
```{r, eval=FALSE}
ggplot(data = ohi_data, aes(y = OHI_score, x = HDI, color=georegion_one))
```
<br>
2. Are these two approaches the same?
```{r, eval=FALSE}
ggplot(data = ohi_data, aes(y=OHI_score, x = HDI, color=georegion_one)) +
geom_point()
ggplot(data = ohi_data) +
geom_point(aes(y = OHI_score, x = HDI, color=georegion_one))
```
<br>
**Answers**
1. The code is missing a geom to describe how the data should be plotted.
2. These two approaches result in the same plot here, but there could be downstream effects as more layers are added.
---
<br>
<br>
**More about the aes function**
The arguments within `aes()` link variables in the dataframe to some aspect of plot appearance. As we have discussed, x and y describe the axes, but other arguments can be added to describe a z variable (e.g. size or color or shape of points). Here are some examples of aes arguments:
* *color* color of lines/points
* *fill* color within polygons
* *label* name
* *linetype* type of line
* *shape* style of point
* *alpha* transparency (0-1)
* *size* size of shape
This is very powerful! Let's explore.
Changing the point size:
```{r aes-size}
ggplot(data = ohi_data, aes(x = OHI_score, y = HDI, size = coastal_pop)) +
geom_point()
```
<br>
Changing the color: continuous variable
```{r aes-color}
ggplot(data = ohi_data, aes(x = OHI_score, y = HDI, color = coastal_pop)) +
geom_point()
```
<br>
Changing the color: discrete variable
```{r aes-color_discrete}
ggplot(data = ohi_data, aes(x = OHI_score, y = HDI, color = georegion_one)) +
geom_point()
```
<br>
Changing shape of points
```{r aes_shape}
ggplot(data = ohi_data, aes(x = OHI_score, y = HDI, shape = georegion_one)) +
geom_point()
````
<br>
Adding labels
```{r}
#This doesn't add the labels like it seems like it should:
ggplot(data = ohi_data, aes(x = OHI_score, y = HDI, label=country)) +
geom_point(aes(x = OHI_score, y = HDI))
# To do this we have to add a geom_text function
ggplot(data = ohi_data, aes(x = OHI_score, y = HDI, label=country)) +
geom_point(aes(x = OHI_score, y = HDI)) +
geom_text()
```
### Step 3: Customize your plot
So far, the plots we have created are fairly ugly and hard to read. We will now improve these basic plots using a stepwise approach.
#### Themes
I do not like the default ggplot2 figures because I find them too busy. A quick way to improve plot appearance is to use themes. Many themes are built into the `ggplot2` package. For example, `theme_bw()` removes the gray background. Once you start typing `theme_` a list of options will pop up.
```{r themes}
ggplot(data = ohi_data, aes(x = OHI_score, y = HDI)) +
geom_point() +
theme_bw()
```
<br>
The [ggthemes](https://yutannihilation.github.io/allYourFigureAreBelongToUs/ggthemes/) package provides many additional themes (including a Tufte theme..which is very clean and data oriented). The [**`ggplot2`** extensions website](https://www.ggplot2-exts.org) provides a list of packages that extend the capabilities of **`ggplot2`**, including additional themes.
I often create my own themes to make figures that work well in publications or presentations. This also gives my figures a consistent look (without having to remember from figure to figure the size of labels, etc.). I have found that storing my themes on Github works well. Here is an example of a theme I created named "scatterTheme":
```{r my theme}
source('https://raw.githubusercontent.com/OHI-Science/ohiprep/master/src/R/scatterTheme.txt')
ggplot(data = ohi_data, aes(x = OHI_score, y = HDI)) +
geom_point() +
scatterTheme
```
#### Labels: axis, plot, legend
One of the first things you will often want to do is alter labels for: titles, axes, figure legends, etc. These modifications involve manipulating the theme function and can quickly get complicated, and I typically have to Google the specifics or refer to a [cheatsheet](https://www.rstudio.com/wp-content/uploads/2016/11/ggplot2-cheatsheet-2.1.pdf), despite using ggplot2 for years and years and years.
But, some key changes are easy to make using the labs function:
```{r labels}
ggplot(data = ohi_data, aes(y = OHI_score, x = HDI, color=georegion_one)) +
geom_point() +
labs(y = "OHI score, 2017",
x = "Human Development Index",
title = "Countries with high human development have more sustainable oceans",
color = "Georegion") + # if color doesn't work, use "fill"
theme_bw()
```
<br>
<br>
---
> **We interrupt this section on customizing your plot for an exercise (5 min)**
1. Make a histogram of the OHI_score variable and color by the georegion_one variable.
2. How would you make all the bars on your histogram light gray? Hint: use argument `fill = "lightgray"`. Where is the best place to add this in your code to get this to work?
3. Play with some themes and customizing title and axes labels. Try changing the text sizes and angles (refer to the [cheatsheet](https://www.rstudio.com/wp-content/uploads/2016/11/ggplot2-cheatsheet-2.1.pdf)).
<br>
**Answers (no peeking)**
```{r, echo=TRUE, eval=FALSE}
# 1. This one is tricky because the color aesthetic only does the outline of the bars.
# If you got that far, you were halfway there.
# You will need to use the fill argument to color shapes
my_plot <- ggplot(data = ohi_data, aes(x=OHI_score, fill=georegion_one)) +
geom_histogram()
my_plot
# 2. This was something that confused me for a while. My instinct was to add it to the aes function....BUT NO!!!
# The arguments in aes should correspond to a column in the dataframe. The best place for this argument is in
# the geom function (and not in an aes function)
ggplot(data = ohi_data, aes(x=OHI_score)) +
geom_histogram(fill="lightgray")
# 3.
my_plot + # the plot created in question 1 continued...
labs(x = "OHI score",
y = "Number of countries",
title = "Distribution of OHI scores") +
theme_light() +
theme(legend.title = element_blank(),
axis.text.x = element_text(angle = 45, hjust = 1, size = 14),
axis.text.y = element_text(size = 14),
axis.title = element_text(size = 16)
)
```
**STOP: commit, pull and push to github**
**We will now continue with customizing your plot.....**
---
<br>
#### Global changes to plot attributes
It is easy to make global changes to your plot's appearance (these go outside the aes function). Here are some options:
* *color* color of lines/points
* *fill* color within polygons
* *label* if points are a character
* *linetype* type of line
* *shape* style of point
* *alpha* transparency (0-1)
* *size* size of shape
Here are the R shapes with their reference numbers:
![](img/shapes.png)
<br>
Here are the R line types with their reference numbers:
![](img/lines.png)
<br>
With this information, we can improve the appearance of one of our previous figures:
```{r fig_improve}
ggplot(data = ohi_summary, aes(x = georegions, y = OHI_score_average)) +
geom_bar(stat="identity", fill = "lightgray") +
geom_jitter(data=ohi_data, aes(x=georegion_one, y=OHI_score), color="red", size=3, alpha=0.3) +
theme_bw()
```
#### Color
One of the more challenging aspects of creating a good plot is selecting colors. We are here to help!
**Hint 1**
Unless you are doing something very simple (e.g. 1-3 colors), I recommend using established color palettes. There are many color palette packages (here is a good resource: https://github.com/EmilHvitfeldt/r-color-palettes), but one of the best known is [RColorBrewer](http://colorbrewer2.org/#type=sequential&scheme=BuGn&n=3).
Here we will explore using the RColorBrewer palettes.
Install the RColorBrewer and colorspace packages (only needs to be done once). Both RColorBrewer and colorspace have nice palettes and colorspace has additional functions for dealing with color.
```{r color_packs, eval=FALSE}
install.packages("RColorBrewer")
install.packages("colorspace")
```
Load packages into working space:
```{r load_color}
library("RColorBrewer")
library("colorspace")
```
To see the available palettes in RColorBrewer:
```{r colorbrewer2}
display.brewer.all()
```
To select a palette:
```{r palette}
my_palette <- brewer.pal(n=9, "YlOrRd")
```
**Hint 2**
R uses hexidecimal to represent colors. Hexadecimal is a base-16 number system used to describe color. Red, green, and blue are each represented by two characters (#rrggbb). Each character has 16 possible symbols: 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F
“00” can be interpreted as 0.0 and “FF” as 1.0, i.e., red= #FF0000 , black=#000000, white = #FFFFFF
Two additional characters (with the same scale) can be added to the end to describe transparency (#rrggbbaa)
A color palette is actually just a simple vector of hexidecimal values:
```{r hexidecimal}
my_palette
```
I always use hexidecimal format for colors in R because it is the most direct approach.
<br>
**Hint 3**
The function you will want to use to specify color in ggplot2 depends on whether the color is mapped to a discrete/categorical data variable, or a continuous variable. There are a LOT of options in ggplot2, but these are the approaches I have settled on because they are the most flexible:
![](img/color_R_ggplot_functions.png)
<br>
In the following case we map color to a continuous variable, so we will use the scale_color_gradientn function with the palette we selected above:
```{r palette_cont}
ggplot(data = ohi_data, aes(x = OHI_score, y = OHI_trend, color = HDI)) +
geom_point(size =3) +
scale_colour_gradientn(colors = my_palette)
```
<br>
This function takes a vector of colors and interpolates between the colors to get a gradient.
If we are mapping color to a discrete variable, we will use the scale_color_manual function:
```{r palette_discrete}
# lets use a discrete color scale
my_palette <- brewer.pal(n=12, "Set3")
ggplot(data = ohi_data, aes(x = OHI_score, y = HDI, color = georegion_one)) +
geom_point(size = 3) +
scale_color_manual(values = my_palette)
# Note the first 7 of the 12 colors are used in the plot
```
The scale_color_manual function also has a lot of great arguments that allow you to control which colors are associated with each factor level, the names used in the legend, and other controls.
**Hint 4**
If the "color" functions aren't working, try the "fill" version of the function.
<br>
---
> **Challenge**
With all of this information in hand, please take a few minutes to create a plot using the fake dataset we will create below (or one of the other datasets we have worked with).
```{r exercise data}
# making a fake dataframe
fake_data <- data.frame(animal = rep(c("cat", "dog", "hamster"), each=10),
year = 2011:2020,
values = c(rnorm(n=10, 5, 1) * seq(0.1, 0.5, length.out=10),
rnorm(n=10, 8, 1) * seq(0.1, 0.5, length.out=10),
rnorm(n=10, 10, 1) * seq(0.1, 0.5, length.out=10)))
## Add your code to create a plot:
```
**Answers (no peeking!)**
Here is one approach, but there is a lot more to do to make this really nice!
```{r answers_make_plot, eval=FALSE, warning=FALSE, error=FALSE}
library(ggthemes)
ggplot(data = fake_data, aes(x = as.factor(year), y = values, group=animal, color=animal)) +
geom_point(size = 3) +
geom_line(size=2, alpha = 0.5) +
labs(x = "year", color = "") +
theme_tufte()
```
---
<br>
## Saving plots
After creating your plot, use the `ggsave()` function to save your plot. This function allows you easily change the dimension, resolution, and format of your plot:
```{r ggsave-example, eval=FALSE, warning=FALSE, error=FALSE}
my_plot <- ggplot(data = fake_data, aes(x = as.factor(year), y = values, group=animal, color=animal)) +
geom_point(size = 3) +
geom_line(size=2, alpha = 0.5) +
labs(x = "year", color = "") +
theme_tufte()
ggsave("name_of_file.png", my_plot, width = 15, height = 10, dpi=300)
```
<br>
Note: The parameters `width` and `height` also determine the font size in the saved plot.
## Arranging plots
I am a huge fan of cowplots for making multiplot figures. Here is a nice [introduction](https://cran.r-project.org/web/packages/cowplot/vignettes/introduction.html).
```{r cowplot_package, eval=FALSE}
install.packages("cowplot")
```
```{r cowplot}
library(cowplot)
score_vs_trend <- ggplot(data=ohi_data, aes(x=OHI_score, y=OHI_trend)) +
geom_point(size=3, alpha=0.4)
score_vs_trend # notice that the default theme has been changed....I really like this theme!
score_vs_HDI <- ggplot(data=ohi_data, aes(x=OHI_score, y=HDI)) +
geom_point(size=3, alpha=0.4) +
geom_smooth()
plot_grid(score_vs_trend, score_vs_HDI, labels = c('A', 'B'))
```
## Interactive plots
So as you can see, `ggplot2` is a fantastic package for visualizing data. But there are some additional packages that let you make plots interactive. `plotly`, `gganimate`. I use plotly all the time to check my data!
```{r plotly_install, eval=FALSE}
install.packages("plotly")
```
```{r plotly_example}
library(plotly)
score_vs_HDI <- ggplot(data=ohi_data, aes(x=OHI_score, y=HDI, text=paste0("Country: ", country))) +
geom_point(size=3, alpha=0.4)
ggplotly(score_vs_HDI)
```
## Save and push to GitHub