- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 facet_wrap 并且还能够绘制次要 y 轴。然而,标签并没有绘制在轴附近,而是绘制得很远。我意识到如果我了解如何操纵 grobs 的 gtable (t,b,l,r) 的坐标系,这一切都会得到解决。有人可以解释他们实际描述的方式和内容 - t:r = c(4,8,4,4) 是什么意思。
辅助 yaxis 与 ggplot 有很多链接,但是当 nrow/ncol 大于 1 时,它们会失败。所以请教我网格几何和 grobs 位置管理的基础知识。
编辑:代码
this is the final code written by me :
library(ggplot2)
library(gtable)
library(grid)
library(data.table)
library(scales)
# Data
diamonds$cut <- sample(letters[1:13], nrow(diamonds), replace = TRUE)
dt.diamonds <- as.data.table(diamonds)
d1 <- dt.diamonds[,list(revenue = sum(price),
stones = length(price)),
by=c("clarity", "cut")]
setkey(d1, clarity, cut)
# The facet_wrap plots
p1 <- ggplot(d1, aes(x = clarity, y = revenue, fill = cut)) +
geom_bar(stat = "identity") +
labs(x = "clarity", y = "revenue") +
facet_wrap( ~ cut) +
scale_y_continuous(labels = dollar, expand = c(0, 0)) +
theme(axis.text.x = element_text(angle = 90, hjust = 1),
axis.text.y = element_text(colour = "#4B92DB"),
legend.position = "bottom")
p2 <- ggplot(d1, aes(x = clarity, y = stones, colour = "red")) +
geom_point(size = 4) +
labs(x = "", y = "number of stones") + expand_limits(y = 0) +
scale_y_continuous(labels = comma, expand = c(0, 0)) +
scale_colour_manual(name = '', values = c("red", "green"),
labels = c("Number of Stones"))+
facet_wrap( ~ cut) +
theme(axis.text.y = element_text(colour = "red")) +
theme(panel.background = element_rect(fill = NA),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_rect(fill = NA, colour = "grey50"),
legend.position = "bottom")
# Get the ggplot grobs
xx <- ggplot_build(p1)
g1 <- ggplot_gtable(xx)
yy <- ggplot_build(p2)
g2 <- ggplot_gtable(yy)
nrow = length(unique(xx$panel$layout$ROW))
ncol = length(unique(xx$panel$layout$COL))
npanel = length(xx$panel$layout$PANEL)
pp <- c(subset(g1$layout, grepl("panel", g1$layout$name), se = t:r))
g <- gtable_add_grob(g1, g2$grobs[grepl("panel", g1$layout$name)],
pp$t, pp$l, pp$b, pp$l)
hinvert_title_grob <- function(grob){
widths <- grob$widths
grob$widths[1] <- widths[3]
grob$widths[3] <- widths[1]
grob$vp[[1]]$layout$widths[1] <- widths[3]
grob$vp[[1]]$layout$widths[3] <- widths[1]
grob$children[[1]]$hjust <- 1 - grob$children[[1]]$hjust
grob$children[[1]]$vjust <- 1 - grob$children[[1]]$vjust
grob$children[[1]]$x <- unit(1, "npc") - grob$children[[1]]$x
grob
}
j = 1
k = 0
for(i in 1:npanel){
if ((i %% ncol == 0) || (i == npanel)){
k = k + 1
index <- which(g2$layout$name == "axis_l-1") # Which grob
yaxis <- g2$grobs[[index]] # Extract the grob
ticks <- yaxis$children[[2]]
ticks$widths <- rev(ticks$widths)
ticks$grobs <- rev(ticks$grobs)
ticks$grobs[[1]]$x <- ticks$grobs[[1]]$x - unit(1, "npc")
ticks$grobs[[2]] <- hinvert_title_grob(ticks$grobs[[2]])
yaxis$children[[2]] <- ticks
if (k == 1)#to ensure just once d secondary axisis printed
g <- gtable_add_cols(g,g2$widths[g2$layout[index,]$l],
max(pp$r[j:i]))
g <- gtable_add_grob(g,yaxis,max(pp$t[j:i]),max(pp$r[j:i])+1,
max(pp$b[j:i])
, max(pp$r[j:i]) + 1, clip = "off", name = "2ndaxis")
j = i + 1
}
}
# inserts the label for 2nd y-axis
loc_1st_yaxis_label <- c(subset(g$layout, grepl("ylab", g$layout$name), se
= t:r))
loc_2nd_yaxis_max_r <- c(subset(g$layout, grepl("2ndaxis", g$layout$name),
se = t:r))
zz <- max(loc_2nd_yaxis_max_r$r)+1
loc_1st_yaxis_label$l <- zz
loc_1st_yaxis_label$r <- zz
index <- which(g2$layout$name == "ylab")
ylab <- g2$grobs[[index]] # Extract that grob
ylab <- hinvert_title_grob(ylab)
ylab$children[[1]]$rot <- ylab$children[[1]]$rot + 180
g <- gtable_add_grob(g, ylab, loc_1st_yaxis_label$t, loc_1st_yaxis_label$l
, loc_1st_yaxis_label$b, loc_1st_yaxis_label$r
, clip = "off", name = "2ndylab")
grid.draw(g)
@Sandy 这是代码和its output
唯一的问题是,在最后一行中,第二个 y 轴标签在面板内。我试图解决这个问题,但无法解决
最佳答案
您的 gtable_add_cols()
和 gtable_add_grob()
命令有问题。我在下面添加了评论。
更新到 ggplot2 v2.2.0
library(ggplot2)
library(gtable)
library(grid)
library(data.table)
library(scales)
diamonds$cut <- sample(letters[1:4], nrow(diamonds), replace = TRUE)
dt.diamonds <- as.data.table(diamonds)
d1 <- dt.diamonds[,list(revenue = sum(price),
stones = length(price)),
by=c("clarity", "cut")]
setkey(d1, clarity, cut)
# The facet_wrap plots
p1 <- ggplot(d1, aes(x = clarity, y = revenue, fill = cut)) +
geom_bar(stat = "identity") +
labs(x = "clarity", y = "revenue") +
facet_wrap( ~ cut, nrow = 2) +
scale_y_continuous(labels = dollar, expand = c(0, 0)) +
theme(axis.text.x = element_text(angle = 90, hjust = 1),
axis.text.y = element_text(colour = "#4B92DB"),
legend.position = "bottom")
p2 <- ggplot(d1, aes(x = clarity, y = stones, colour = "red")) +
geom_point(size = 4) +
labs(x = "", y = "number of stones") + expand_limits(y = 0) +
scale_y_continuous(labels = comma, expand = c(0, 0)) +
scale_colour_manual(name = '', values = c("red", "green"),
labels =c("Number of Stones")) +
facet_wrap( ~ cut, nrow = 2) +
theme(axis.text.y = element_text(colour = "red")) +
theme(panel.background = element_rect(fill = NA),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_rect(fill = NA, colour = "grey50"),
legend.position = "bottom")
# Get the ggplot grobs
g1 <- ggplotGrob(p1)
g2 <- ggplotGrob(p2)
# Grab the panels from g2 and overlay them onto the panels of g1
pp <- c(subset(g1$layout, grepl("panel", g1$layout$name), select = t:r))
g <- gtable_add_grob(g1, g2$grobs[grepl("panel", g1$layout$name)],
pp$t, pp$l, pp$b, pp$l)
# Function to invert labels
hinvert_title_grob <- function(grob){
widths <- grob$widths
grob$widths[1] <- widths[3]
grob$widths[3] <- widths[1]
grob$vp[[1]]$layout$widths[1] <- widths[3]
grob$vp[[1]]$layout$widths[3] <- widths[1]
grob$children[[1]]$hjust <- 1 - grob$children[[1]]$hjust
grob$children[[1]]$vjust <- 1 - grob$children[[1]]$vjust
grob$children[[1]]$x <- unit(1, "npc") - grob$children[[1]]$x
grob
}
# Get the y label from g2, and invert it
index <- which(g2$layout$name == "ylab-l")
ylab <- g2$grobs[[index]] # Extract that grob
ylab <- hinvert_title_grob(ylab)
# Put the y label into g, to the right of the right-most panel
# Note: Only one column and one y label
g <- gtable_add_cols(g, g2$widths[g2$layout[index, ]$l], pos = max(pp$r))
g <-gtable_add_grob(g,ylab, t = min(pp$t), l = max(pp$r)+1,
b = max(pp$b), r = max(pp$r)+1,
clip = "off", name = "ylab-r")
# Get the y axis from g2, reverse the tick marks and the tick mark labels,
# and invert the tick mark labels
index <- which(g2$layout$name == "axis-l-1-1") # Which grob
yaxis <- g2$grobs[[index]] # Extract the grob
ticks <- yaxis$children[[2]]
ticks$widths <- rev(ticks$widths)
ticks$grobs <- rev(ticks$grobs)
plot_theme <- function(p) {
plyr::defaults(p$theme, theme_get())
}
tml <- plot_theme(p1)$axis.ticks.length # Tick mark length
ticks$grobs[[1]]$x <- ticks$grobs[[1]]$x - unit(1, "npc") + tml
ticks$grobs[[2]] <- hinvert_title_grob(ticks$grobs[[2]])
yaxis$children[[2]] <- ticks
# Put the y axis into g, to the right of the right-most panel
# Note: Only one column, but two y axes - one for each row of the facet_wrap plot
g <- gtable_add_cols(g, g2$widths[g2$layout[index, ]$l], pos = max(pp$r))
nrows = length(unique(pp$t)) # Number of rows
g <- gtable_add_grob(g, rep(list(yaxis), nrows),
t = unique(pp$t), l = max(pp$r)+1,
b = unique(pp$b), r = max(pp$r)+1,
clip = "off", name = paste0("axis-r-", 1:nrows))
# Get the legends
leg1 <- g1$grobs[[which(g1$layout$name == "guide-box")]]
leg2 <- g2$grobs[[which(g2$layout$name == "guide-box")]]
# Combine the legends
g$grobs[[which(g$layout$name == "guide-box")]] <-
gtable:::cbind_gtable(leg1, leg2, "first")
grid.newpage()
grid.draw(g)
SO 不是一个教程站点,这可能会招致其他 SO 用户的愤怒,但是评论太多了。
仅使用一个绘图面板绘制图表(即没有分面),
library(ggplot2)
p <- ggplot(mtcars, aes(x = mpg, y = disp)) + geom_point()
获取 ggplot grob。
g <- ggplotGrob(p)
探索剧情:
1) gtable_show_layout()
给出绘图的 gtable 布局图。中间的大空间是绘图面板的位置。面板左侧和下方的列包含 y 轴和 x 轴。整个地 block 周围有一个边距。索引给出了数组中每个单元格的位置。请注意,例如,面板位于第四列的第三行。
gtable_show_layout(g)
2) 布局数据框。 g$layout
返回一个数据帧,其中包含图中包含的 grobs 的名称以及它们在 gtable 中的位置:t、l、b 和 r(代表顶部、左侧、右侧和底部)。请注意,例如,面板位于 t=3、l=4、b=3、r=4。这与上面从图中获得的面板位置相同。
g$layout
3) 布局图试图给出行和列的高度和宽度,但它们往往会重叠。相反,请使用 g$widths
和 g$heights
。 1null 宽度和高度是绘图面板的宽度和高度。请注意,1null 是第三个高度和第四个宽度 - 又是 3 和 4。
现在绘制一个 facet_wrap 和一个 facet_grid 图。
p1 <- ggplot(mtcars, aes(x = mpg, y = disp)) + geom_point() +
facet_wrap(~ carb, nrow = 1)
p2 <- ggplot(mtcars, aes(x = mpg, y = disp)) + geom_point() +
facet_grid(. ~ carb)
g1 <- ggplotGrob(p1)
g2 <- ggplotGrob(p2)
这两个图看起来一样,但它们的 gtable 不同。此外,组件 grobs 的名称不同。
通常获取包含常见类型 grob 索引(即 t、l、b 和 r)的布局数据帧的子集很方便;说所有的面板。
pp1 <- subset(g1$layout, grepl("panel", g1$layout$name), select = t:r)
pp2 <- subset(g2$layout, grepl("panel", g2$layout$name), select = t:r)
例如,请注意所有面板都在第 4 行(pp1$t
、pp2$t
)。pp1$r
指的是包含绘图面板的列;pp1$r + 1
指的是面板右侧的列;max(pp1$r)
指的是包含面板的最右边的列;max(pp1$r) + 1
指的是包含面板的最右侧列右侧的列;
等等。
最后,绘制多行的 facet_wrap 图。
p3 <- ggplot(mtcars, aes(x = mpg, y = disp)) + geom_point() +
facet_wrap(~ carb, nrow = 2)
g3 <- ggplotGrob(p3)
像以前一样探索绘图,但还对布局数据框进行子集化以包含面板的索引。
pp3 <- subset(g3$layout, grepl("panel", g3$layout$name), select = t:r)
如您所料,pp3
告诉您绘图面板位于三列(4、7 和 10)和两行(4 和 8)中。
这些索引用于向 gtable 添加行或列,以及向 gtable 添加 grobs 时。使用 ?gtable_add_rows
和 gtable_add_grob
检查这些命令。
此外,学习一些grid
,尤其是如何构造grobs,以及单位的使用(一些资源在SO上的r-grid
标签中给出。
关于r - 如何管理 gtable() 的 t、b、l、r 坐标以正确绘制次要 y 轴的标签和刻度线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37984000/
如何使用 plot() 在 XY 图中绘制第二条线,以不同的比例(如本例(紫色线))? 第一行(红色)我的 R 代码是这样的: p <- sqlQuery(ch,"SELECT wl,param1 F
我正在寻找一种将折线图步骤设置为仅完整数字步骤的方法,例如 1,2,3,4,5..... 目前它看起来像这样: 这些是我的选择。我搜索了很多但找不到解决方案。 let options = {
我的问题是如何将 Y 轴刻度的间隔从 0.2 更改为 0.1?我已经尝试了一切,但我很困!帖子底部堆叠条形图的图片 dpi=600 #pixels per square inch A <- c(
有没有办法根据当前数据集在 D3 轴上动态设置 ticks。我遇到的问题是我的时间范围(x 轴)可能变化很大。对于一些数据集来说,它是几年的值(value),对于其他数据集来说是几个月,在某些情况下只
我已经使用默认参数创建了一个 dojo 蜘蛛图。我需要隐藏轴标签(刻度上的数据值,而不是轴标题)。 我已经尝试过'ticks: false',但是它不适用于蜘蛛图。 require(["dojo/_b
有没有一种简单的方法可以在绘图 Axis 上获得自定义缩放比例? 例如,semilogy 函数提供 {x, log10(y)} 缩放比例,这样就可以自动放大/缩小并自动调整刻度和标签。我想对 {x,
如何修改图形和图表的 y Axis 刻度?我想要这样的东西:my_figure.y_range.end = my_figure.y_range.end * 1.3 所以我想要更高一点的y轴。谢谢! 最
我正在尝试使用 recharts 添加图表一些货币的最新汇率。数据显示正确,但图表始终从 0 开始并略高于最大值。 图表是正确的,但它不需要从 0 开始,因为这样做,它几乎是一条线。 这是图表的图片:
我有一个 SWT Scale 小部件,我需要在刻度上的刻度上添加标签。 有没有办法做到这一点?也许在 slider 小部件上? 谢谢 最佳答案 这可能不是您所要求的,但您可以在 Scale 小部件旁边
这是一个从 .xlsx 文件中读取数据并利用 Plotly 库绘制气泡图的程序。这是 .xlsx 文件的原始数据: 1991 1992 1993 1994 1995
我这里有一个代码笔 - https://codepen.io/anon/pen/yvgJKB 我有一个简单的堆积条形图。 我想将其制作成一个组件,因此我需要传入值以使其可重用 x 缩放函数返回d.da
让我们看一个基本的演示折线图: jsfiddle $(function () { $('#container').highcharts({ //all the code there 我想强制
是否可以在 t-sql 中获得像 DateTime.Ticks 这样的 C# 内容? 感谢帮助 最佳答案 您不太可能从 SQL 中获得与 DateTime.Ticks 相同的精度,因为 SQL 不能以
我正在使用 Bokeh 生成散点图,每个 X 值具有不同的 Y 值。当 Bokeh 生成绘图时,它会根据绘制的值的数量自动填充 x 轴间距。我希望 x 轴上的所有值均匀分布,无论单个数据点的数量如何。
我使用下面的代码使用谷歌图表生成折线图 google.charts.load('current', {packages: ['corechart', 'line']});
我正在尝试在 d3 中构建堆积条形图。 这是我的 jsfiddle: http://jsfiddle.net/maneesha/gwjkgruk/4/ 我正在尝试修复它,使 y 轴从零开始。 我认为这
我有一个 d3 时间刻度图表。目前,轴刻度为每个数据对象呈现一个日期。例如,数据的范围可以是 1 天的数据、1 个月内 2 周的数据、5 个月的数据甚至更多。 理想情况下,我们希望显示带有周数的刻度,
当使用“Cassic”折线图时,我可以为 hAxis 分配刻度,还有这样的格式和标题: var options = { hAxis: { format:'h a', title
我的累积折线图没有正确构建 yScale。 给定要构建图表的数据: var data = [{ key: "Page view", values: [ ["2013-07-01 00:
在 y 轴上使用两个具有正常整数值的 DateAxisSeries(x 轴)我的 jqPlot 将 y 刻度呈现两次。 像这样: 2| 2| 1| 1| 0|_____________________
我是一名优秀的程序员,十分优秀!