简体   繁体   中英

Elegant ways to visualise positive/negative time series data with ggplot?

I have some time series data that represents cumulative sums of a number of data series over time, basically money flowing in and out of a market. Some are positive and some are negative, but the different strands of data do of course sum to the money flow for the market as a whole. I have been mulling over how to visualise this using ggplot and so far small multiples seem to be the clearest way to go - see below for image and code.

Does anybody have any other suggestions for a striking visualisation with such data, using R and (preferably) ggplot ? I have tried using geom_area but that gets very messy and I can't seem to work out a way to have each data series shown clearly, even after playing with the stack keyword.

小倍数

require(ggplot2)
require(scales)
require(gridExtra)

mymelt <- structure(list(mydate = structure(c(15340, 15340, 15340, 15340,
15340, 15340, 15340, 15340, 15340, 15340, 15340, 15340, 15371,
15371, 15371, 15371, 15371, 15371, 15371, 15371, 15371, 15371,
15371, 15371, 15400, 15400, 15400, 15400, 15400, 15400, 15400,
15400, 15400, 15400, 15400, 15400, 15431, 15431, 15431, 15431,
15431, 15431, 15431, 15431, 15431, 15431, 15431, 15431, 15461,
15461, 15461, 15461, 15461, 15461, 15461, 15461, 15461, 15461,
15461, 15461, 15492, 15492, 15492, 15492, 15492, 15492, 15492,
15492, 15492, 15492, 15492, 15492, 15522, 15522, 15522, 15522,
15522, 15522, 15522, 15522, 15522, 15522, 15522, 15522, 15553,
15553, 15553, 15553, 15553, 15553, 15553, 15553, 15553, 15553,
15553, 15553), class = "Date"), variable = c("b", "bc", "f",
"in", "it", "l", "of", "o", "pr", "s", "total", "tr", "b", "bc",
"f", "in", "it", "l", "of", "o", "pr", "s", "total", "tr", "b",
"bc", "f", "in", "it", "l", "of", "o", "pr", "s", "total", "tr",
"b", "bc", "f", "in", "it", "l", "of", "o", "pr", "s", "total",
"tr", "b", "bc", "f", "in", "it", "l", "of", "o", "pr", "s",
"total", "tr", "b", "bc", "f", "in", "it", "l", "of", "o", "pr",
"s", "total", "tr", "b", "bc", "f", "in", "it", "l", "of", "o",
"pr", "s", "total", "tr", "b", "bc", "f", "in", "it", "l", "of",
"o", "pr", "s", "total", "tr"), value = c(-23, 6.90000000000001,
459.799999999999, -403.6, -56.1, -95, -13.8, 32.6, 121.5, -15.7,
26.2000000000007, 12.5, -25.1, 238.3, 1047.2, -803.2, -151.5,
-260.5, -59.6, -93.8, 461.5, -37.7, 26.7999999999993, -288.8,
-46.4, 249, 1289.8, -783.2, -188.1, -414.9, -77.7, -61, 928.4,
-36.8, 17.4000000000015, -841.7, -46.5, 276.2, 1384.8, -541.1,
-71.8999999999999, -433.3, -61.3, -28.3, 494.699999999999, -23.4,
-14.5999999999985, -964.5, -46.1, 376.2, 1020.1, -119.4, 56.8000000000001,
-447.7, -9.50000000000001, 14.2, -9.20000000000164, 2.5, -42.7999999999993,
-880.6, -52.9, 345.5, 892.599999999999, -241.8, 144.3, -428.2,
-3.30000000000001, 91.9, -294.800000000002, -5.19999999999999,
-42.1999999999971, -490.1, -64.5, 379.7, 679.299999999999, -143.1,
185.9, -419.8, -4.30000000000001, 182.4, -421.900000000002, 1.80000000000001,
-59.8999999999978, -435.2, -80.2, 422.2, 645.499999999998, -391.4,
76.6000000000001, -387.4, -1.70000000000001, 211.2, -131.500000000002,
-10.6, -40.8999999999978, -393.6), fill = c("#A4D3EE80", "#A478AB80",
"#01AEF080", "#8DC73F80", "#F8931D80", "#FFAAAA80", "#8C8C8C",
"#D38D5F80", "#23238E80", "#77B9B780", "#C8373780", "#EEDD8280",
"#A4D3EE80", "#A478AB80", "#01AEF080", "#8DC73F80", "#F8931D80",
"#FFAAAA80", "#8C8C8C", "#D38D5F80", "#23238E80", "#77B9B780",
"#C8373780", "#EEDD8280", "#A4D3EE80", "#A478AB80", "#01AEF080",
"#8DC73F80", "#F8931D80", "#FFAAAA80", "#8C8C8C", "#D38D5F80",
"#23238E80", "#77B9B780", "#C8373780", "#EEDD8280", "#A4D3EE80",
"#A478AB80", "#01AEF080", "#8DC73F80", "#F8931D80", "#FFAAAA80",
"#8C8C8C", "#D38D5F80", "#23238E80", "#77B9B780", "#C8373780",
"#EEDD8280", "#A4D3EE80", "#A478AB80", "#01AEF080", "#8DC73F80",
"#F8931D80", "#FFAAAA80", "#8C8C8C", "#D38D5F80", "#23238E80",
"#77B9B780", "#C8373780", "#EEDD8280", "#A4D3EE80", "#A478AB80",
"#01AEF080", "#8DC73F80", "#F8931D80", "#FFAAAA80", "#8C8C8C",
"#D38D5F80", "#23238E80", "#77B9B780", "#C8373780", "#EEDD8280",
"#A4D3EE80", "#A478AB80", "#01AEF080", "#8DC73F80", "#F8931D80",
"#FFAAAA80", "#8C8C8C", "#D38D5F80", "#23238E80", "#77B9B780",
"#C8373780", "#EEDD8280", "#A4D3EE80", "#A478AB80", "#01AEF080",
"#8DC73F80", "#F8931D80", "#FFAAAA80", "#8C8C8C", "#D38D5F80",
"#23238E80", "#77B9B780", "#C8373780", "#EEDD8280")), .Names = c("mydate",
"variable", "value", "fill"), row.names = c(NA, 96L), class = "data.frame")

myvals <- mymelt[mymelt$mydate == mymelt$mydate[nrow(mymelt)],] ## last date in mymelt should always be same as plotenddate as we subset earlier
mymelt <- within(mymelt, variable <- factor(variable, as.character(myvals[order(myvals$value, decreasing = T),]$variable), ordered = TRUE))

p <- ggplot(mymelt, aes(x = mydate, y = value)) +
     geom_area(aes(fill = variable), position = "stack") +
     facet_wrap(~ variable, ncol = 4) +
     theme(axis.text.x = element_text(size = 8, angle = 90, colour = "grey50")) +
     theme()
print(p)

Normally I would advise you to stack the panels horizontally so that every time series would have common x-axis. However, that's not going to work if you don't want to change the scales as @GavinSimpson suggested. In this case it's probably better to place the panels next to each other, but removing some unnecessary data-ink (see Tufte, 2001 ).

Generally, you don't need legend, because panel name already tells you the name of your variables. That also removes the need for rainbow colours. I would also avoid using geom_area and use geom_line instead - your effects still stands out without overfilling the plot with the heavy geometric area. After that there are small fine details - you remove minor grid to decrease grid density, you change axis text size, you decrease the width of the geom_line . You change theme to theme_bw to remove all the gray crap. Finally, it helps if the height of the plot will be more or less 50% of its width in this specific case. The only issue with this solution is that the date labels on x axis are quite small.

p <- ggplot(mymelt, aes(x = mydate, y = value)) +
  geom_line(lwd=0.3) +
  facet_grid(. ~ variable) +
  theme_bw() +
  theme(axis.text.x = element_text(size = 5, angle = 90),
        axis.text.y = element_text(size = 8),
        axis.title.x = element_text(vjust = 0),
        axis.ticks = element_blank(), 
        panel.grid.minor = element_blank())
print(p)
ggsave(plot=p, filename="plot.png", width = 8, height = 4)   

在此输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM