Load packages
library(tidyverse)
library(plotly)
library(nycflights13)
Demo: mtcars (small)
The mtcars dataset is tiny and should be easy to plot.
Use hp to define colors. Plot the following:
hp as continuous. ggplot does the conversion for you.
hp where each value gets its own color. You do the conversion manually
hp as groups. You manually create the bins.
dat1 <- mtcars %>%
mutate(colorManual = rainbow(n())[rank(hp)]) %>%
mutate(colorBinned = cut(hp, 1:30*10))
p1 <- ggplot(dat1, aes(wt, mpg, color = hp)) +
geom_point() +
ggtitle("Continuous")
p2 <- ggplot(dat1, aes(wt, mpg, color = colorManual)) +
geom_point() +
ggtitle("Manual")
p3 <- ggplot(dat1, aes(wt, mpg, color = colorBinned)) +
geom_point() +
ggtitle("Binned")
ggplotly(p1)
ggplotly(p2)
ggplotly(p3)
Demo: flights (larger)
The flights data is slightly large. If you plot thousands of points, you will see your system slow down since javascript has to be created for each point. You can adjust the number of records n in the script.
Use distance to define colors. Plot the following:
distance as continuous. ggplot does the conversion for you.
distance where each value gets its own color. You do the conversion manually
distance as groups. You manually create the bins.
n <- 100
dat2 <- flights %>%
mutate(colorManual = rainbow(n())[rank(distance)]) %>%
mutate(colorBinned = cut(distance, 1:50*100)) %>%
tail(n)
p3 <- ggplot(dat2, aes(arr_delay, dep_delay, color = distance)) +
geom_point() +
ggtitle("Continuous")
p4 <- ggplot(dat2, aes(arr_delay, dep_delay, color = colorManual)) +
geom_point() +
ggtitle("Manual")
p5 <- ggplot(dat2, aes(arr_delay, dep_delay, color = colorBinned)) +
geom_point() +
ggtitle("Binned")
ggplotly(p3)
ggplotly(p4)
ggplotly(p5)
Conclusion
I recommend using ggplot’s internal feature to convert continuous columns into colors.
Plotly produces dynamic graphics built in javascript. These should only be used for small datasets since file size will explode and performance will degrade with large data.
LS0tCnRpdGxlOiAiZ2dwbG90bHkgd2l0aCBsb3RzIG9mIGNvbG9ycyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyBMb2FkIHBhY2thZ2VzCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KG55Y2ZsaWdodHMxMykKYGBgCgoKIyBEZW1vOiBtdGNhcnMgKHNtYWxsKQoKVGhlIG10Y2FycyBkYXRhc2V0IGlzIHRpbnkgYW5kIHNob3VsZCBiZSBlYXN5IHRvIHBsb3QuIAoKVXNlIGBocGAgdG8gZGVmaW5lIGNvbG9ycy4gUGxvdCB0aGUgZm9sbG93aW5nOgoKKiBgaHBgIGFzIGNvbnRpbnVvdXMuIGdncGxvdCBkb2VzIHRoZSBjb252ZXJzaW9uIGZvciB5b3UuCiogYGhwYCB3aGVyZSBlYWNoIHZhbHVlIGdldHMgaXRzIG93biBjb2xvci4gWW91IGRvIHRoZSBjb252ZXJzaW9uIG1hbnVhbGx5CiogYGhwYCBhcyBncm91cHMuIFlvdSBtYW51YWxseSBjcmVhdGUgdGhlIGJpbnMuCgpgYGB7cn0KZGF0MSA8LSBtdGNhcnMgJT4lCiAgbXV0YXRlKGNvbG9yTWFudWFsID0gcmFpbmJvdyhuKCkpW3JhbmsoaHApXSkgJT4lCiAgbXV0YXRlKGNvbG9yQmlubmVkID0gY3V0KGhwLCAxOjMwKjEwKSkKCnAxIDwtIGdncGxvdChkYXQxLCBhZXMod3QsIG1wZywgY29sb3IgPSBocCkpICsKICBnZW9tX3BvaW50KCkgKwogIGdndGl0bGUoIkNvbnRpbnVvdXMiKQoKcDIgPC0gZ2dwbG90KGRhdDEsIGFlcyh3dCwgbXBnLCBjb2xvciA9IGNvbG9yTWFudWFsKSkgKwogIGdlb21fcG9pbnQoKSArIAogIGdndGl0bGUoIk1hbnVhbCIpCgpwMyA8LSBnZ3Bsb3QoZGF0MSwgYWVzKHd0LCBtcGcsIGNvbG9yID0gY29sb3JCaW5uZWQpKSArCiAgZ2VvbV9wb2ludCgpICsgCiAgZ2d0aXRsZSgiQmlubmVkIikKCmdncGxvdGx5KHAxKSAKZ2dwbG90bHkocDIpIApnZ3Bsb3RseShwMykgCmBgYAoKIyBEZW1vOiBmbGlnaHRzIChsYXJnZXIpCgpUaGUgZmxpZ2h0cyBkYXRhIGlzIHNsaWdodGx5IGxhcmdlLiBJZiB5b3UgcGxvdCB0aG91c2FuZHMgb2YgcG9pbnRzLCB5b3Ugd2lsbCBzZWUgeW91ciBzeXN0ZW0gc2xvdyBkb3duIHNpbmNlIGphdmFzY3JpcHQgaGFzIHRvIGJlIGNyZWF0ZWQgZm9yIGVhY2ggcG9pbnQuIFlvdSBjYW4gYWRqdXN0IHRoZSBudW1iZXIgb2YgcmVjb3JkcyBgbmAgaW4gdGhlIHNjcmlwdC4KClVzZSBgZGlzdGFuY2VgIHRvIGRlZmluZSBjb2xvcnMuIFBsb3QgdGhlIGZvbGxvd2luZzoKCiogYGRpc3RhbmNlYCBhcyBjb250aW51b3VzLiBnZ3Bsb3QgZG9lcyB0aGUgY29udmVyc2lvbiBmb3IgeW91LgoqIGBkaXN0YW5jZWAgd2hlcmUgZWFjaCB2YWx1ZSBnZXRzIGl0cyBvd24gY29sb3IuIFlvdSBkbyB0aGUgY29udmVyc2lvbiBtYW51YWxseQoqIGBkaXN0YW5jZWAgYXMgZ3JvdXBzLiBZb3UgbWFudWFsbHkgY3JlYXRlIHRoZSBiaW5zLgoKCmBgYHtyfQpuIDwtIDEwMAoKZGF0MiA8LSBmbGlnaHRzICU+JQogIG11dGF0ZShjb2xvck1hbnVhbCA9IHJhaW5ib3cobigpKVtyYW5rKGRpc3RhbmNlKV0pICU+JQogIG11dGF0ZShjb2xvckJpbm5lZCA9IGN1dChkaXN0YW5jZSwgMTo1MCoxMDApKSAlPiUKICB0YWlsKG4pCgpwMyA8LSBnZ3Bsb3QoZGF0MiwgYWVzKGFycl9kZWxheSwgZGVwX2RlbGF5LCBjb2xvciA9IGRpc3RhbmNlKSkgKyAKICBnZW9tX3BvaW50KCkgKwogIGdndGl0bGUoIkNvbnRpbnVvdXMiKQoKcDQgPC0gZ2dwbG90KGRhdDIsIGFlcyhhcnJfZGVsYXksIGRlcF9kZWxheSwgY29sb3IgPSBjb2xvck1hbnVhbCkpICsgCiAgZ2VvbV9wb2ludCgpICsKICBnZ3RpdGxlKCJNYW51YWwiKQoKcDUgPC0gZ2dwbG90KGRhdDIsIGFlcyhhcnJfZGVsYXksIGRlcF9kZWxheSwgY29sb3IgPSBjb2xvckJpbm5lZCkpICsgCiAgZ2VvbV9wb2ludCgpICsKICBnZ3RpdGxlKCJCaW5uZWQiKQoKZ2dwbG90bHkocDMpCmdncGxvdGx5KHA0KQpnZ3Bsb3RseShwNSkKCgpgYGAKCiMgQ29uY2x1c2lvbgoKSSByZWNvbW1lbmQgdXNpbmcgZ2dwbG90J3MgaW50ZXJuYWwgZmVhdHVyZSB0byBjb252ZXJ0IGNvbnRpbnVvdXMgY29sdW1ucyBpbnRvIGNvbG9ycy4gCgpQbG90bHkgcHJvZHVjZXMgZHluYW1pYyBncmFwaGljcyBidWlsdCBpbiBqYXZhc2NyaXB0LiBUaGVzZSBzaG91bGQgb25seSBiZSB1c2VkIGZvciBzbWFsbCBkYXRhc2V0cyBzaW5jZSBmaWxlIHNpemUgd2lsbCBleHBsb2RlIGFuZCBwZXJmb3JtYW5jZSB3aWxsIGRlZ3JhZGUgd2l0aCBsYXJnZSBkYXRhLg==