shen_qing = "#212A54" # 深青色
qian_qing = "#234C73" # 浅青色
cui_qing = "#263E47" # 翠青色
dan_qing = "#F2F8FF" # 淡青色
hutao_hong = "#793328" # 胡桃红
dan_feng = "#FFF8F0" # 淡粉色
tao_you = "#C0BAB6" # 陶釉色
library(plotly)
library(ggplot2)1 plotly package
- This section also includes Chapter 2 - Overview in Book: Interactive web-based data visualization with R, plotly, and shiny, which has more details about
plotlypackage.
1.1 Set UP
1.2 IVRPS Chapter 2: Basic Information
plotly R package is powered by the Javascript library plotly.js. A plotly object is initialized with a plot_ly() function.
head(diamonds)# A tibble: 6 × 10
carat cut color clarity depth table price x y z
<dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
4 0.29 Premium I VS2 62.4 58 334 4.2 4.23 2.63
5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
plot_ly()tries to find a sensible geometric representation of that information forNote that column name is formatted with
~Nameinplot_ly(), which is different fromggplot2packageNameorvars(Name).
subplot(
plot_ly(diamonds, x=~cut),
plot_ly(diamonds, x=~cut, y=~clarity, colors="Accent"),
plot_ly(diamonds, x=~cut, color=~clarity, colors="Accent"),
nrows = 2)Plot 1/2/3
- To specify the color directly, use
I()function to declar the color value as “asis”.
plot_ly(diamonds, x=~cut,
color=I("tomato"),
stroke=I("royalblue"),
span = I(3)) |>
layout(title = "Histogram with I() function")1.2.1 Translate ggplot2 to plotly
In Figure 1, ggplotly() can translate a ggplot2 object into a plotly object.
p <- ggplot(diamonds, aes(x=log(carat), y=log(price))) +
geom_hex(bins = 100)
ggplotly(p)1.2.2 add_ as layers and |> as connection
Plotly implements geoms in a similar fashion as ggplot2, functions that start in add_ add a layer to the plot (e.g.: add_lines, add_bars), making it easy to combine series into a single chart, as in Figure 2.
plot_ly(mtcars, x=~disp) |>
add_markers(y=~mpg, text = rownames(mtcars)) |>
add_lines(y=~fitted(loess(mpg ~ disp)))1.2.3 Data in plotly.js
Use
plotly_json()to see the JSON representation of the plotly object.Use
jasonliteto quickly check jason elements. Check out the package information.
library(jsonlite)
library(tidyverse)
p <- plot_ly(diamonds, x = ~cut, color = ~clarity, colors = "Accent")
p_jason <- plotly_json(p, FALSE, pretty = TRUE) |>
fromJSON()
colnames(p_jason$data) [1] "x" "type" "name" "marker" "textfont" "error_y"
[7] "error_x" "xaxis" "yaxis" "frame"
1.2.4 Work directly with plotly.js
add_trace(type = "scatter", mode = "xxx") function allows you to work directly with plotly.js. This function is a low-level interface to plotly.js, compared to other functions like add_markers.
set.seed(99)
plot_ly() |>
add_trace(
type = "scatter",
mode = "markers+lines+text",
x = 4:6,
y = 4:6,
text = replicate(3, praise::praise("You are ${adjective}! 🙌")),
textposition = "right",
hoverinfo = "text",
textfont = list(family = "MiSans", size = 16)
) |>
layout(xaxis = list(range = c(3, 8)))1.3 IVRPS Chapter 3: Scattered Trace
The trace is general layer in plot.js, which can be specified with a type. The trace layer with type scatter is for drawing geometries like points, lines, text, and polygons.
1.3.1 add_lines and add_paths
add_linesensures lines are drawn according to the ordering of x, which is desirable for a time series plotting. The figure below starts with the lowest value of x —1967-07-01|12.6.add_pathsdraws lines in the order of the data frame (row ordering). As shown in figure below, points starts with the point in the first row—2005-07-01|2.2— then2005-08-01|2.7.If x is sorted from lowest to highest,
add_pathswith be equivalent toadd_lines.
data
library(kableExtra)
data(economics, package = "ggplot2")
economics |>
select(date, psavert) |>
arrange(psavert) |>
head(5) |>
kable()| date | psavert |
|---|---|
| 2005-07-01 | 2.2 |
| 2005-08-01 | 2.7 |
| 2005-09-01 | 2.7 |
| 2005-06-01 | 2.9 |
| 2005-04-01 | 3.1 |
add_paths
p <- economics |>
arrange(psavert) |>
plot_ly(x=~date, y=~psavert)
add_paths(p)add_lines
add_lines(p)add_paths with sorted x values
economics |>
arrange(date) |>
plot_ly(x=~date, y=~psavert, color = I("tomato")) |>
add_paths()1.3.2 Attributes: Group data into sub-gemometry
- Some attributes include color, alpha, symbol, stroke, span, size, linetype.
library(lubridate)
econ <- economics |>
mutate(yr = year(date), mnth = month(date))
plot_ly(econ, x=~mnth, y=~uempmed) |>
add_lines(color=~ordered(yr), colors="Accent")Scatter traces can be specified with a mode of markers (add_markers with a numeric x and y axis). This results in scatterplot.
- Use
alphato adjust the transparancy of scatter points. It can combat with overplotting (points with exactly same x and y values). A location with more points shows less transparent.
subplot(
plot_ly(mpg, x=~cty, y=~hwy, name = "default"),
plot_ly(mpg, x=~cty, y=~hwy) |>
add_markers(alpha = .2, name = "alpha")
)- Use
colorandcolorbar()to produce color trace and color schema. The default colorscale isviridis.
subplot(
plot_ly(mpg, x=~cty, y=~hwy) |>
add_markers(alpha = .2, color=~cyl, showlegend = FALSE) |>
colorbar(title = "Viridis"),
plot_ly(mpg, x=~cty, y=~hwy) |>
add_markers(alpha = .2, color=~factor(cyl), showlegend = FALSE)
)Use
colors=argument to alter the default color scale. (similar toggplot2::scale_color_brewer()). It can be one of the following three types:- color palette name (e.g., check out
RColorBrewer::brewer.pal.info) - a munually specified vector of colors
c("#132B43", "#56B1F7") - a color interpolation function like
colorRamp()orscales::colour_ramp(), i.e.,colorRamp(c("red", "white", "blue"))
- color palette name (e.g., check out
rownames(RColorBrewer::brewer.pal.info) [1] "BrBG" "PiYG" "PRGn" "PuOr" "RdBu" "RdGy"
[7] "RdYlBu" "RdYlGn" "Spectral" "Accent" "Dark2" "Paired"
[13] "Pastel1" "Pastel2" "Set1" "Set2" "Set3" "Blues"
[19] "BuGn" "BuPu" "GnBu" "Greens" "Greys" "Oranges"
[25] "OrRd" "PuBu" "PuBuGn" "PuRd" "Purples" "RdPu"
[31] "Reds" "YlGn" "YlGnBu" "YlOrBr" "YlOrRd"
1.3.3 color= and stroke=
The color argument is meant to control the ‘fill-color’ of a geometric object, whereas stroke is meant to control the ‘outline-color’ of a geometric object.
p <- plot_ly(mpg, x=~cty, y=~hwy)
subplot(
p |>
add_markers(alpha = .2, color=~cyl, showlegend = FALSE),
p |>
add_markers(color=I("black"), stroke=~cyl, showlegend = FALSE)
)- Use
symbolargument to map data values to different shape.
- Use
symbolsto specify certain visual values: “circle”, “diamond” etc.
p <- plot_ly(mpg, x=~cty, y=~hwy, alpha = .3)
subplot(
p |> add_markers(symbol =~factor(cyl), color=I("black"),
symbols = 9:12),
p |> add_markers(symbol =~factor(cyl), color=I("black"),
symbols = c("triangle-up", "diamond", "circle"))
)- Use
spanto control width of the stroke (outline).
subplot(
plot_ly(mpg, x=~cty, y=~hwy, alpha=.5) |>
add_markers(symbol=I(18), stroke=I("black"), span=I(1)),
plot_ly(mpg, x=~cty, y=~hwy, alpha=.5) |>
add_markers(symbol=I(18), stroke=I("black"), span=I(3))
)- Use
sizeto control the area of markers.
- Use
sizesto control the min and max values of size in pixles.
p <- plot_ly(mpg, x=~cty, y=~hwy, alpha = .3)
subplot(
p |> add_markers(size=I(30), name="fixed"),
p |> add_markers(size=~cyl, sizes = c(1, 100), name="custom")
)- Use
linetypeto control line types
econ <- economics |>
mutate(yr = year(date), mnth = month(date)) |>
filter(yr %in% 1967:1972)
plot_ly(data = econ, x=~mnth, y=~uempmed, linetype =~factor(yr), size = I(3)) |>
add_lines()1.4 IVRPS Chapter 5: Bars and Histogram
1.4.1 add_bars() and add_histogram()
Use add_bars() and add_histogram() to wrap the bar plot and the histogram plot. The bar plots requires the height information of bars (x and y), while the histogram requires only x variables.
If the count is calculated in R (using count() for categorical data and hist(plot=FALSE) for continous data), add_bars is faster than add_histogram in terms of page load time.
subplot(
plot_ly(data = diamonds, x=~price) |> add_histogram(name="Histogram", color=I(shen_qing)),
plot_ly(data = diamonds, x=~price, y=~carat) |> add_bars(name="Bar", color=I(hutao_hong))
)1.4.2 Multiple subplots: lapply + subplot
In following code, group_split() is similar to base::split().
one_plot function allows to plot a histogram with x-axis as “price”. add_annotations() adds names of subplots on the top.
library(tidyverse)
one_plot <- function(d) {
plot_ly(d, x = ~price) %>%
add_annotations(
~unique(clarity), x = 0.5, y = 1,
xref = "paper", yref = "paper", showarrow = FALSE
)
}
diamonds |>
group_split(clarity) |>
lapply(one_plot) |>
subplot(nrows = 2, shareX = TRUE, titleX = FALSE) |>
hide_legend()1.4.3 layout(barmode = "stack"): stacked barplot
subplot(
plot_ly(diamonds, x=~cut, color=~clarity) |>
add_histogram() |>
layout(barmode="stack") |>
hide_guides(),
diamonds |>
group_by(cut, clarity) |>
count() |>
group_by(cut) |>
mutate(prop = n / sum(n)) |>
plot_ly(x=~cut, color=~clarity, y=~prop) |>
add_bars() |>
layout(barmode="stack")
)