在 X 轴上排列的 ggplot2 图表下方绘制 table 个单独的数据
Plot a table of separate data below a ggplot2 graph that lines up on the X axis
我想创建一个包含简单多线 ggplot2 图表的绘图,其中 table 单独(但相关)的数据位于图表下方,由图表的 X 轴排列。数据 table 的列名确实与图表的 x 轴匹配(1 到 24 小时),但其中一列专用于必要的行名。
这里分别是图表和数据 table:
为了简洁起见,数据 table 在 16 点被截断,但确实延长到 24 点。
整个上午我都在尝试在 gridExtra 中调整不同的参数,例如 nrow、ncol、高度和宽度,但最简单的解决方案只能产生比较合理的结果。下面的代码和图片是我实现的最好的:
library(gridExtra)
p1 <- ggplot(load_forecast_plot, aes(group=Load_Type, y=Load_Values, x=Hour, colour = Load_Type)) +
geom_line(size = 1) +
scale_x_continuous(breaks = c(1:24))
p1 <- ggplotGrob(p1)
p2<-tableGrob(df)
grid.arrange(p1, p2, top = paste("Load and Weather Error Power Grid", Sys.Date()-1, sep = " "))
grid.draw(tableGrob(MISO_wx_PrevDay_error_test,theme=ttheme_minimal(base_size = 5)))
产生:
我希望图表更大,而 table 更小,并尽可能沿 x 轴对齐。我研究了将 table 转换为 ggplot2 对象的示例,但这些示例在绘图中具有相同的数据,并且 table 与我的不同。
以下是我的可重现示例数据。任何帮助深表感谢!谢谢你。
ggplot 图的数据:
dput(load_forecast_plot)
structure(list(Hour = c(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11,
11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16,
17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22,
22, 22, 23, 23, 23, 24, 24, 24), Load_Type = c("Load", "DA_MTLF",
"BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF",
"Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load",
"DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF",
"BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF",
"Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load",
"DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF",
"BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF",
"Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load",
"DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF",
"BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF"
), Load_Values = c(59141, 59260, 57862, 56493, 56470, 54964,
54480, 54553, 52996, 53270, 53252, 51683, 53050, 52520, 50845,
53020, 51723, 49627, 53844, 51907, 49293, 56956, 55069, 52700,
60975, 60036, 58251, 65595, 65023, 63881, 69796, 69023, 68776,
73392, 72517, 72591, 76412, 74896, 75452, 78454, 76538, 77547,
79959, 77782, 79256, 81315, 78851, 80627, 82478, 79921, 81763,
82638, 80027, 81896, 81244, 78906, 80328, 78484, 76627, 77304,
77187, 75130, 75391, 74495, 72612, 72776, 69736, 68216, 68488,
64844, 63756, 64145)), row.names = c(NA, -72L), class = c("tbl_df",
"tbl", "data.frame"))
数据table:
dput(df)
structure(list(WX_Error = c("CloudCover", "DewPoint", "RainFall",
"SolarRadiation", "Temperature", "WindSpeed"), `1` = c("-13.72%",
"-0.41°F", "0in", "0min", "-0.86°F", "0.26mph"), `2` = c("-8.52%",
"-0.05°F", "-0.01in", "0min", "-1.2°F", "-0.11mph"), `3` = c("-9.22%",
"-0.41°F", "-0.01in", "0min", "-1.26°F", "-1.41mph"), `4` = c("-14.57%",
"-0.98°F", "-0.01in", "0min", "-1.48°F", "-0.99mph"), `5` = c("-15.81%",
"-0.83°F", "-0.01in", "0min", "-0.83°F", "-1.58mph"), `6` = c("-13.43%",
"-0.61°F", "0in", "-0.43min", "-0.46°F", "0.48mph"), `7` = c("-14.23%",
"-0.28°F", "0in", "7.91min", "-1.15°F", "-0.43mph"), `8` = c("-2.29%",
"0.1°F", "0in", "1.3min", "-0.72°F", "0.51mph"), `9` = c("-3.63%",
"0.2°F", "0in", "1.96min", "-0.94°F", "-0.9mph"), `10` = c("4.73%",
"0.25°F", "0in", "-2.99min", "-0.69°F", "0.25mph"), `11` = c("-8.68%",
"0.8°F", "0.01in", "5.03min", "-0.83°F", "0.81mph"), `12` = c("-4.42%",
"0.64°F", "0.01in", "2.34min", "-0.3°F", "0.9mph"), `13` = c("-15.06%",
"0.49°F", "-0.01in", "8.08min", "0.29°F", "0.44mph"), `14` = c("-25.35%",
"0.55°F", "-0.01in", "14.4min", "0.47°F", "0.59mph"), `15` = c("-19.36%",
"0.6°F", "-0.01in", "10.76min", "0.44°F", "1.29mph"), `16` = c("-8.1%",
"0.17°F", "-0.01in", "5.03min", "0.29°F", "1.26mph"), `17` = c("-21.01%",
"-0.27°F", "-0.01in", "11.74min", "1.52°F", "0.72mph"), `18` = c("-22.84%",
"-0.74°F", "-0.01in", "12.77min", "2.17°F", "1.34mph"), `19` = c("-18.57%",
"-0.55°F", "0in", "10.35min", "0.46°F", "1.13mph"), `20` = c("-10.39%",
"-0.91°F", "0.03in", "5.6min", "0.65°F", "0.71mph"), `21` = c("-6.65%",
"-0.28°F", "0.06in", "1.66min", "-0.5°F", "-0.56mph"), `22` = c("-0.2%",
"-0.4°F", "-0.01in", "0min", "-0.33°F", "-1.35mph"), `23` = c("4.39%",
"0.11°F", "-0.01in", "0min", "-0.5°F", "-0.47mph"), `24` = c("-5.65%",
"0.64°F", "0.01in", "0min", "-0.43°F", "0.35mph")), row.names = c(NA,
-6L), groups = structure(list(Date = structure(c(18407, 18407,
18407, 18407, 18407, 18407), class = "Date"), wx_vars = c("CloudCover",
"DewPoint", "RainFall", "SolarRadiation", "Temperature", "WindSpeed"
), .rows = list(1L, 2L, 3L, 4L, 5L, 6L)), row.names = c(NA, -6L
), class = c("tbl_df", "tbl", "data.frame"), .drop = FALSE), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"))
您可以将 table 格式化为 ggplot 对象,然后使用 patchwork 包为您处理对齐。
library(ggplot2)
library(patchwork)
p1 <- ggplot(load_forecast_plot, aes(group=Load_Type, y=Load_Values, x=Hour, colour = Load_Type)) +
geom_line(size = 1) +
scale_x_continuous(breaks = c(1:24))
p2 <- gridExtra::tableGrob(df)
# Set widths/heights to 'fill whatever space I have'
p2$widths <- unit(rep(1, ncol(p2)), "null")
p2$heights <- unit(rep(1, nrow(p2)), "null")
# Format table as plot
p3 <- ggplot() +
annotation_custom(p2)
# Patchwork magic
p1 + p3 + plot_layout(ncol = 1)
我知道现在看起来不太好;您必须稍微修改一下设备大小和文本大小。但是,问题是关于对齐的,这似乎没问题。
编辑:
如果正确设置 x 轴,您也可以将轴刻度与列匹配:
p1 <- ggplot(load_forecast_plot, aes(group=Load_Type, y=Load_Values, x=Hour, colour = Load_Type)) +
geom_line(size = 1) +
scale_x_continuous(breaks = c(1:24),
limits = c(-1, 24),
expand = c(0,0.5))
或者您可以将第二列设置为轴文本:
p1 <- ggplot(load_forecast_plot, aes(group=Load_Type, y=Load_Values, x=Hour, colour = Load_Type)) +
geom_line(size = 1) +
scale_x_continuous(breaks = c(1:24),
expand = c(0,0.5))
p2 <- gridExtra::tableGrob(df)[, -c(1:2)]
p2$widths <- unit(rep(1, ncol(p2)), "null")
p2$heights <- unit(rep(1, nrow(p2)), "null")
p3 <- ggplot() +
annotation_custom(p2) +
scale_y_discrete(breaks = rev(df$WX_Error),
limits = c(rev(df$WX_Error), ""))
p1 + p3 + plot_layout(ncol = 1)
编辑 2:
我也没有看到任何文本大小选项,但您可以通过以下方式手动更改字体大小:
is_text <- vapply(p2$grobs, inherits, logical(1), "text")
p2$grobs[is_text] <- lapply(p2$grobs[is_text], function(text) {
text$gp$fontsize <- 8
text
})
经过一番摆弄之后,我得到了这个:
library(ggpubr)
p1 <- ggplot(load_forecast_plot, aes(group=Load_Type, y=Load_Values, x=Hour, colour = Load_Type)) +
geom_line(size = 1) +
scale_x_continuous(breaks = c(1:24)) +
theme(legend.position="top")+
theme(plot.margin=unit(c(0,1,0,3.1),"cm"))
p1
p2 <- ggtexttable(df)
plot <- ggarrange(p1, p2,
ncol = 1, nrow = 2,
heights = c(10,3))
plot
只需调整边距和设备尺寸,直到或多或少对齐。虽然有点变通,我刚刚看到的@teunbrand 的解决方案现在看起来更有希望。
我想创建一个包含简单多线 ggplot2 图表的绘图,其中 table 单独(但相关)的数据位于图表下方,由图表的 X 轴排列。数据 table 的列名确实与图表的 x 轴匹配(1 到 24 小时),但其中一列专用于必要的行名。
这里分别是图表和数据 table:
为了简洁起见,数据 table 在 16 点被截断,但确实延长到 24 点。
整个上午我都在尝试在 gridExtra 中调整不同的参数,例如 nrow、ncol、高度和宽度,但最简单的解决方案只能产生比较合理的结果。下面的代码和图片是我实现的最好的:
library(gridExtra)
p1 <- ggplot(load_forecast_plot, aes(group=Load_Type, y=Load_Values, x=Hour, colour = Load_Type)) +
geom_line(size = 1) +
scale_x_continuous(breaks = c(1:24))
p1 <- ggplotGrob(p1)
p2<-tableGrob(df)
grid.arrange(p1, p2, top = paste("Load and Weather Error Power Grid", Sys.Date()-1, sep = " "))
grid.draw(tableGrob(MISO_wx_PrevDay_error_test,theme=ttheme_minimal(base_size = 5)))
产生:
我希望图表更大,而 table 更小,并尽可能沿 x 轴对齐。我研究了将 table 转换为 ggplot2 对象的示例,但这些示例在绘图中具有相同的数据,并且 table 与我的不同。
以下是我的可重现示例数据。任何帮助深表感谢!谢谢你。
ggplot 图的数据:
dput(load_forecast_plot)
structure(list(Hour = c(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5,
5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11,
11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16,
17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 21, 22,
22, 22, 23, 23, 23, 24, 24, 24), Load_Type = c("Load", "DA_MTLF",
"BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF",
"Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load",
"DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF",
"BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF",
"Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load",
"DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF",
"BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF",
"Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load",
"DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF",
"BC_MTLF", "Load", "DA_MTLF", "BC_MTLF", "Load", "DA_MTLF", "BC_MTLF"
), Load_Values = c(59141, 59260, 57862, 56493, 56470, 54964,
54480, 54553, 52996, 53270, 53252, 51683, 53050, 52520, 50845,
53020, 51723, 49627, 53844, 51907, 49293, 56956, 55069, 52700,
60975, 60036, 58251, 65595, 65023, 63881, 69796, 69023, 68776,
73392, 72517, 72591, 76412, 74896, 75452, 78454, 76538, 77547,
79959, 77782, 79256, 81315, 78851, 80627, 82478, 79921, 81763,
82638, 80027, 81896, 81244, 78906, 80328, 78484, 76627, 77304,
77187, 75130, 75391, 74495, 72612, 72776, 69736, 68216, 68488,
64844, 63756, 64145)), row.names = c(NA, -72L), class = c("tbl_df",
"tbl", "data.frame"))
数据table:
dput(df)
structure(list(WX_Error = c("CloudCover", "DewPoint", "RainFall",
"SolarRadiation", "Temperature", "WindSpeed"), `1` = c("-13.72%",
"-0.41°F", "0in", "0min", "-0.86°F", "0.26mph"), `2` = c("-8.52%",
"-0.05°F", "-0.01in", "0min", "-1.2°F", "-0.11mph"), `3` = c("-9.22%",
"-0.41°F", "-0.01in", "0min", "-1.26°F", "-1.41mph"), `4` = c("-14.57%",
"-0.98°F", "-0.01in", "0min", "-1.48°F", "-0.99mph"), `5` = c("-15.81%",
"-0.83°F", "-0.01in", "0min", "-0.83°F", "-1.58mph"), `6` = c("-13.43%",
"-0.61°F", "0in", "-0.43min", "-0.46°F", "0.48mph"), `7` = c("-14.23%",
"-0.28°F", "0in", "7.91min", "-1.15°F", "-0.43mph"), `8` = c("-2.29%",
"0.1°F", "0in", "1.3min", "-0.72°F", "0.51mph"), `9` = c("-3.63%",
"0.2°F", "0in", "1.96min", "-0.94°F", "-0.9mph"), `10` = c("4.73%",
"0.25°F", "0in", "-2.99min", "-0.69°F", "0.25mph"), `11` = c("-8.68%",
"0.8°F", "0.01in", "5.03min", "-0.83°F", "0.81mph"), `12` = c("-4.42%",
"0.64°F", "0.01in", "2.34min", "-0.3°F", "0.9mph"), `13` = c("-15.06%",
"0.49°F", "-0.01in", "8.08min", "0.29°F", "0.44mph"), `14` = c("-25.35%",
"0.55°F", "-0.01in", "14.4min", "0.47°F", "0.59mph"), `15` = c("-19.36%",
"0.6°F", "-0.01in", "10.76min", "0.44°F", "1.29mph"), `16` = c("-8.1%",
"0.17°F", "-0.01in", "5.03min", "0.29°F", "1.26mph"), `17` = c("-21.01%",
"-0.27°F", "-0.01in", "11.74min", "1.52°F", "0.72mph"), `18` = c("-22.84%",
"-0.74°F", "-0.01in", "12.77min", "2.17°F", "1.34mph"), `19` = c("-18.57%",
"-0.55°F", "0in", "10.35min", "0.46°F", "1.13mph"), `20` = c("-10.39%",
"-0.91°F", "0.03in", "5.6min", "0.65°F", "0.71mph"), `21` = c("-6.65%",
"-0.28°F", "0.06in", "1.66min", "-0.5°F", "-0.56mph"), `22` = c("-0.2%",
"-0.4°F", "-0.01in", "0min", "-0.33°F", "-1.35mph"), `23` = c("4.39%",
"0.11°F", "-0.01in", "0min", "-0.5°F", "-0.47mph"), `24` = c("-5.65%",
"0.64°F", "0.01in", "0min", "-0.43°F", "0.35mph")), row.names = c(NA,
-6L), groups = structure(list(Date = structure(c(18407, 18407,
18407, 18407, 18407, 18407), class = "Date"), wx_vars = c("CloudCover",
"DewPoint", "RainFall", "SolarRadiation", "Temperature", "WindSpeed"
), .rows = list(1L, 2L, 3L, 4L, 5L, 6L)), row.names = c(NA, -6L
), class = c("tbl_df", "tbl", "data.frame"), .drop = FALSE), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"))
您可以将 table 格式化为 ggplot 对象,然后使用 patchwork 包为您处理对齐。
library(ggplot2)
library(patchwork)
p1 <- ggplot(load_forecast_plot, aes(group=Load_Type, y=Load_Values, x=Hour, colour = Load_Type)) +
geom_line(size = 1) +
scale_x_continuous(breaks = c(1:24))
p2 <- gridExtra::tableGrob(df)
# Set widths/heights to 'fill whatever space I have'
p2$widths <- unit(rep(1, ncol(p2)), "null")
p2$heights <- unit(rep(1, nrow(p2)), "null")
# Format table as plot
p3 <- ggplot() +
annotation_custom(p2)
# Patchwork magic
p1 + p3 + plot_layout(ncol = 1)
我知道现在看起来不太好;您必须稍微修改一下设备大小和文本大小。但是,问题是关于对齐的,这似乎没问题。
编辑:
如果正确设置 x 轴,您也可以将轴刻度与列匹配:
p1 <- ggplot(load_forecast_plot, aes(group=Load_Type, y=Load_Values, x=Hour, colour = Load_Type)) +
geom_line(size = 1) +
scale_x_continuous(breaks = c(1:24),
limits = c(-1, 24),
expand = c(0,0.5))
或者您可以将第二列设置为轴文本:
p1 <- ggplot(load_forecast_plot, aes(group=Load_Type, y=Load_Values, x=Hour, colour = Load_Type)) +
geom_line(size = 1) +
scale_x_continuous(breaks = c(1:24),
expand = c(0,0.5))
p2 <- gridExtra::tableGrob(df)[, -c(1:2)]
p2$widths <- unit(rep(1, ncol(p2)), "null")
p2$heights <- unit(rep(1, nrow(p2)), "null")
p3 <- ggplot() +
annotation_custom(p2) +
scale_y_discrete(breaks = rev(df$WX_Error),
limits = c(rev(df$WX_Error), ""))
p1 + p3 + plot_layout(ncol = 1)
编辑 2:
我也没有看到任何文本大小选项,但您可以通过以下方式手动更改字体大小:
is_text <- vapply(p2$grobs, inherits, logical(1), "text")
p2$grobs[is_text] <- lapply(p2$grobs[is_text], function(text) {
text$gp$fontsize <- 8
text
})
经过一番摆弄之后,我得到了这个:
library(ggpubr)
p1 <- ggplot(load_forecast_plot, aes(group=Load_Type, y=Load_Values, x=Hour, colour = Load_Type)) +
geom_line(size = 1) +
scale_x_continuous(breaks = c(1:24)) +
theme(legend.position="top")+
theme(plot.margin=unit(c(0,1,0,3.1),"cm"))
p1
p2 <- ggtexttable(df)
plot <- ggarrange(p1, p2,
ncol = 1, nrow = 2,
heights = c(10,3))
plot
只需调整边距和设备尺寸,直到或多或少对齐。虽然有点变通,我刚刚看到的@teunbrand 的解决方案现在看起来更有希望。