выравнивание отдельных не-фасетных графиков в ggplot2 с использованием Rpy2 в Python
Я объединяю два отдельных графика в макет сетки сgrid
как предложено @lgautier в rpy2 с использованием python. Верхний график представляет собой плотность, а нижний - гистограмму:
iris = r('iris')
import pandas
# define layout
lt = grid.layout(2, 1)
vp = grid.viewport(layout = lt)
vp.push()
# first plot
vp_p = grid.viewport(**{'layout.pos.row': 1, 'layout.pos.col':1})
p1 = ggplot2.ggplot(iris) + \
ggplot2.geom_density(aes_string(x="Sepal.Width",
colour="Species")) + \
ggplot2.facet_wrap(Formula("~ Species"))
p1.plot(vp = vp_p)
# second plot
mean_df = pandas.DataFrame({"Species": ["setosa", "virginica", "versicolor"],
"X": [10, 2, 30],
"Y": [5, 3, 4]})
mean_df = pandas.melt(mean_df, id_vars=["Species"])
r_mean_df = get_r_dataframe(mean_df)
p2 = ggplot2.ggplot(r_mean_df) + \
ggplot2.geom_bar(aes_string(x="Species",
y="value",
group="variable",
colour="variable"),
position=ggplot2.position_dodge(),
stat="identity")
vp_p = grid.viewport(**{'layout.pos.row': 2, 'layout.pos.col':1})
p2.plot(vp = vp_p)
то, что я получаю, близко к тому, что я хочу, но графики не совсем выровнены (показано стрелками, которые я добавил): I '
Мне бы хотелось, чтобы регионы сюжета (а не легенды) точно совпадали. Как это может быть достигнуто? разница здесь не так велика, но когда вы добавляете условия к гистограмме ниже или делаете из них гистограмму с точкамиposition_dodge
различия могут стать очень большими, и графики не выровнены.
Стандартное решение ggplot не может быть легко переведено на rpy2:
arrange
по-видимомуgrid_arrange
в :gridExtra
>>> gridExtra = importr("gridExtra")
>>> gridExtra.grid_arrange
ggplotGrob
недоступен изggplot2
, но можно получить доступ следующим образом:
>>> ggplot2.ggplot2.ggplotGrob
Хотя я не знаю, как получить доступ:grid::unit.pmax
>>> grid.unit
>>> grid.unit("pmax")
Error in (function (x, units, data = NULL) :
argument "units" is missing, with no default
rpy2.rinterface.RRuntimeError: Error in (function (x, units, data = NULL) :
argument "units" is missing, with no default
так что'Не ясно, как перевести стандартное решение ggplot2 в rpy2.
редактировать: как отметили другиеgrid::unit.pmax
являетсяgrid.unit_pmax
, Я до сих пор нене знаю, как получить доступ в rpy2widths
параметрgrob
Объекты, хотя, что необходимо, чтобы установить ширину графиков, чтобы быть шириной более широкого графика. Я имею:
gA = ggplot2.ggplot2.ggplotGrob(p1)
gB = ggplot2.ggplot2.ggplotGrob(p2)
g = importr("grid")
print "gA: ", gA
maxWidth = g.unit_pmax(gA.widths[2:5], gB.widths[2:5])
gA.widths
не правильный синтаксис.grob
объектgA
печатает как:
gA: TableGrob (8 x 13) "layout": 17 grobs
z cells name grob
1 0 ( 1- 8, 1-13) background rect[plot.background.rect.350]
2 1 ( 4- 4, 4- 4) panel-1 gTree[panel-1.gTree.239]
3 2 ( 4- 4, 7- 7) panel-2 gTree[panel-2.gTree.254]
4 3 ( 4- 4,10-10) panel-3 gTree[panel-3.gTree.269]
5 4 ( 3- 3, 4- 4) strip_t-1 absoluteGrob[strip.absoluteGrob.305]
6 5 ( 3- 3, 7- 7) strip_t-2 absoluteGrob[strip.absoluteGrob.311]
7 6 ( 3- 3,10-10) strip_t-3 absoluteGrob[strip.absoluteGrob.317]
8 7 ( 4- 4, 3- 3) axis_l-1 absoluteGrob[axis-l-1.absoluteGrob.297]
9 8 ( 4- 4, 6- 6) axis_l-2 zeroGrob[axis-l-2.zeroGrob.298]
10 9 ( 4- 4, 9- 9) axis_l-3 zeroGrob[axis-l-3.zeroGrob.299]
11 10 ( 5- 5, 4- 4) axis_b-1 absoluteGrob[axis-b-1.absoluteGrob.276]
12 11 ( 5- 5, 7- 7) axis_b-2 absoluteGrob[axis-b-2.absoluteGrob.283]
13 12 ( 5- 5,10-10) axis_b-3 absoluteGrob[axis-b-3.absoluteGrob.290]
14 13 ( 7- 7, 4-10) xlab text[axis.title.x.text.319]
15 14 ( 4- 4, 2- 2) ylab text[axis.title.y.text.321]
16 15 ( 4- 4,12-12) guide-box gtable[guide-box]
17 16 ( 2- 2, 4-10) title text[plot.title.text.348]
обновление: достигнут некоторый прогресс в доступе к ширине, но все еще не удается перевести решение. Чтобы установить ширину гробов, у меня есть:
# get grobs
gA = ggplot2.ggplot2.ggplotGrob(p1)
gB = ggplot2.ggplot2.ggplotGrob(p2)
g = importr("grid")
# get max width
maxWidth = g.unit_pmax(gA.rx2("widths")[2:5][0], gB.rx2("widths")[2:5][0])
print gA.rx2("widths")[2:5]
wA = gA.rx2("widths")[2:5]
wB = gB.rx2("widths")[2:5]
print "before: ", wA[0]
wA[0] = robj.ListVector(maxWidth)
print "After: ", wA[0]
print "before: ", wB[0]
wB[0] = robj.ListVector(maxWidth)
print "after:", wB[0]
gridExtra.grid_arrange(gA, gB, ncol=1)
Это работает, но не работает. Вывод:
[[1]]
[1] 0.740361111111111cm
[[2]]
[1] 1null
[[3]]
[1] 0.127cm
before: [1] 0.740361111111111cm
After: [1] max(0.740361111111111cm, sum(1grobwidth, 0.15cm+0.1cm))
before: [1] sum(1grobwidth, 0.15cm+0.1cm)
after: [1] max(0.740361111111111cm, sum(1grobwidth, 0.15cm+0.1cm))
update2: понял, как @baptiste указал, что было бы полезно показать чистую версию R того, что яЯ пытаюсь воспроизвести в rpy2. Вот's чистая версия R:
df