मैं एक बनाने के लिए कोशिश कर रहा हूँ facet_multi_col()
समारोह, के लिए इसी तरह facet_col()
के समारोह ggforce
है कि एक अंतरिक्ष तर्क के साथ एक पहलू लेआउट (जो उपलब्ध नहीं है के लिए अनुमति देता है - facet_wrap()
) - लेकिन अधिक एकाधिक स्तंभों। जैसा कि नीचे दिए गए अंतिम प्लॉट में ( grid.arrange()
मैं के साथ बनाया गया ) नहीं चाहता कि पंक्तियों को आवश्यक रूप से पंक्तियों में संरेखित किया जाए क्योंकि प्रत्येक पहलू में ऊँचाई एक श्रेणीगत y
चर के आधार पर भिन्न होगी जिसे मैं उपयोग करना चाहता हूं।
मैं ggproto
विस्तार मार्गदर्शिका पढ़ने के साथ अपनी गहराई से खुद को अच्छी तरह से पा रहा हूं । मुझे लगता है कि सबसे अच्छा तरीका एक लेआउट मैट्रिक्स पास करना है जहां यह तय करना है कि डेटा के इसी सबसेट के लिए कॉलम को कैसे तोड़ें, और स्पेस पैरामीटर को शामिल करने के लिए facet_col
ggforce में निर्माण करें - प्रश्न का अंत देखें।
मेरे असंतोषजनक विकल्पों का त्वरित चित्रण
कोई पहलू नहीं
library(tidyverse)
library(gapminder)
global_tile <- ggplot(data = gapminder, mapping = aes(x = year, y = fct_rev(country), fill = lifeExp)) +
geom_tile()
global_tile
मैं महाद्वीपों द्वारा साजिश को तोड़ना चाहता हूं। मुझे इतना लंबा फिगर नहीं चाहिए।
facet_wrap ()
global_tile +
facet_wrap(facets = "continent", scales = "free")
facet_wrap()
एक अंतरिक्ष तर्क नहीं है जिसका अर्थ है कि प्रत्येक महाद्वीप में टाइलें अलग-अलग आकार हैं, coord_equal()
जो एक त्रुटि का उपयोग करती हैं
ggforce में facet_col ()
library(ggforce)
global_tile +
facet_col(facets = "continent", scales = "free", space = "free", strip.position = "right") +
theme(strip.text.y = element_text(angle = 0))
साइड पर स्ट्रिप्स की तरह। space
तर्क सभी टाईल्स को समान आकार में सेट करता है। अभी भी एक पृष्ठ पर फिट होने के लिए बहुत लंबा है।
gridExtra में grid.arrange ()
डेटा के लिए एक कॉलम कॉलम जोड़ें जहां प्रत्येक महाद्वीप रखा जाना चाहिए
d <- gapminder %>%
as_tibble() %>%
mutate(col = as.numeric(continent),
col = ifelse(test = continent == "Europe", yes = 2, no = col),
col = ifelse(test = continent == "Oceania", yes = 3, no = col))
head(d)
# # A tibble: 6 x 7
# country continent year lifeExp pop gdpPercap col
# <fct> <fct> <int> <dbl> <int> <dbl> <dbl>
# 1 Afghanistan Asia 1952 28.8 8425333 779. 3
# 2 Afghanistan Asia 1957 30.3 9240934 821. 3
# 3 Afghanistan Asia 1962 32.0 10267083 853. 3
# 4 Afghanistan Asia 1967 34.0 11537966 836. 3
# 5 Afghanistan Asia 1972 36.1 13079460 740. 3
# 6 Afghanistan Asia 1977 38.4 14880372 786. 3
tail(d)
# # A tibble: 6 x 7
# country continent year lifeExp pop gdpPercap col
# <fct> <fct> <int> <dbl> <int> <dbl> <dbl>
# 1 Zimbabwe Africa 1982 60.4 7636524 789. 1
# 2 Zimbabwe Africa 1987 62.4 9216418 706. 1
# 3 Zimbabwe Africa 1992 60.4 10704340 693. 1
# 4 Zimbabwe Africa 1997 46.8 11404948 792. 1
# 5 Zimbabwe Africa 2002 40.0 11926563 672. 1
# 6 Zimbabwe Africa 2007 43.5 12311143 470. 1
facet_col()
प्रत्येक कॉलम के लिए प्लॉट का उपयोग करें
g <- list()
for(i in unique(d$col)){
g[[i]] <- d %>%
filter(col == i) %>%
ggplot(mapping = aes(x = year, y = fct_rev(country), fill = lifeExp)) +
geom_tile() +
facet_col(facets = "continent", scales = "free_y", space = "free", strip.position = "right") +
theme(strip.text.y = element_text(angle = 0)) +
# aviod legends in every column
guides(fill = FALSE) +
labs(x = "", y = "")
}
एक पौराणिक कथा का उपयोग कर बनाने get_legend()
मेंcowplot
library(cowplot)
gg <- ggplot(data = d, mapping = aes(x = year, y = country, fill = lifeExp)) +
geom_tile()
leg <- get_legend(gg)
प्रत्येक कॉलम में देशों की संख्या के आधार पर ऊँचाई के साथ एक लेआउट मैट्रिक्स बनाएँ।
m <-
d %>%
group_by(col) %>%
summarise(row = n_distinct(country)) %>%
rowwise() %>%
mutate(row = paste(1:row, collapse = ",")) %>%
separate_rows(row) %>%
mutate(row = as.numeric(row),
col = col,
p = col) %>%
xtabs(formula = p ~ row + col) %>%
cbind(max(d$col) + 1) %>%
ifelse(. == 0, NA, .)
head(m)
# 1 2 3
# 1 1 2 3 4
# 2 1 2 3 4
# 3 1 2 3 4
# 4 1 2 3 4
# 5 1 2 3 4
# 6 1 2 3 4
tail(m)
# 1 2 3
# 50 1 2 NA 4
# 51 1 2 NA 4
# 52 1 2 NA 4
# 53 NA 2 NA 4
# 54 NA 2 NA 4
# 55 NA 2 NA 4
लाओ g
और leg
एक साथ उपयोग grid.arrange()
मेंgridExtra
library(gridExtra)
grid.arrange(g[[1]], g[[2]], g[[3]], leg, layout_matrix = m, widths=c(0.32, 0.32, 0.32, 0.06))
यह लगभग वही है जो मैं उसके बाद कर रहा हूं, लेकिन मैं संतुष्ट नहीं हूं क) विभिन्न स्तंभों में टाइल्स की चौड़ाई अलग-अलग है क्योंकि देश की लंबाई और महाद्वीप के नाम बराबर नहीं हैं और बी) इसके बहुत सारे कोड हैं जिन्हें प्रत्येक को ट्विक करने की आवश्यकता है समय मैं इस तरह एक भूखंड बनाना चाहता हूं - अन्य आंकड़ों के साथ मैं क्षेत्रों द्वारा पहलुओं को व्यवस्थित करना चाहता हूं, उदाहरण के लिए महाद्वीपों के बजाय "पश्चिमी यूरोप" या देशों की संख्या में परिवर्तन - कोई मध्य एशियाई देश नहीं हैं gapminder
डेटा ।
एक facet_multi_cols () फ़ंक्शन बनाने के साथ प्रगति
मैं एक फंक्शनल मैट्रिक्स को एक फंक्शन फंक्शन पास करना चाहता हूँ, जहाँ मैट्रिक्स प्रत्येक फेशियल को संदर्भित करेगा, और फंक्शन तब प्रत्येक पैनल में स्पेस की संख्या के आधार पर हाइट्स का पता लगा सकता है। उपरोक्त उदाहरण के लिए मैट्रिक्स होगा:
my_layout <- matrix(c(1, NA, 2, 3, 4, 5), nrow = 2)
my_layout
# [,1] [,2] [,3]
# [1,] 1 2 4
# [2,] NA 3 5
जैसा कि ऊपर उल्लेख किया गया है, मैं facet_col()
एक facet_multi_col()
फ़ंक्शन का प्रयास करने और बनाने के लिए कोड से अनुकूलन कर रहा हूं । मैंने उपर्युक्त layout
जैसे मैट्रिक्स प्रदान करने के लिए एक तर्क जोड़ा है my_layout
, इस विचार के साथ, उदाहरण के लिए, facets
तर्क को दिए गए चर के चौथे और पांचवें स्तर को तीसरे कॉलम में प्लॉट किया गया है।
facet_multi_col <- function(facets, layout, scales = "fixed", space = "fixed",
shrink = TRUE, labeller = "label_value",
drop = TRUE, strip.position = 'top') {
# add space argument as in facet_col
space <- match.arg(space, c('free', 'fixed'))
facet <- facet_wrap(facets, col = col, dir = dir, scales = scales, shrink = shrink, labeller = labeller, drop = drop, strip.position = strip.position)
params <- facet$params
params <- facet$layout
params$space_free <- space == 'free'
ggproto(NULL, FacetMultiCols, shrink = shrink, params = params)
}
FacetMultiCols <- ggproto('FacetMultiCols', FacetWrap,
# from FacetCols to allow for space argument to work
draw_panels = function(self, panels, layout, x_scales, y_scales, ranges, coord, data, theme, params) {
combined <- ggproto_parent(FacetWrap, self)$draw_panels(panels, layout, x_scales, y_scales, ranges, coord, data, theme, params)
if (params$space_free) {
widths <- vapply(layout$PANEL, function(i) diff(ranges[[i]]$x.range), numeric(1))
panel_widths <- unit(widths, "null")
combined$widths[panel_cols(combined)$l] <- panel_widths
}
combined
}
# adapt FacetWrap layout to set position on panels following the matrix given to layout in facet_multi_col().
compute_layout = function(self, panels, layout, x_scales, y_scales, ranges, coord, data, theme, params) {
layout <- ggproto_parent(FacetWrap, self)$compute_layout(panels, layout, x_scales, y_scales, ranges, coord, data, theme, params)
# ???
)
मुझे लगता है कि मुझे compute_layout
भाग के लिए कुछ लिखने की आवश्यकता है , लेकिन मुझे यह पता लगाने के लिए संघर्ष कर रहा हूं कि यह कैसे करना है।
grid.arrange
ऊपर के उदाहरण में .. जब तक कि आपका मतलब कुछ अलग न हो? मुझे लगता है कि प्रत्येक कॉलम में अलग-अलग लेबल लंबाई के साथ समान समस्याएं मौजूद होंगी?
grid.arrange
। यह वास्तव में लंबी पोस्ट है इसलिए आपने जो भी कोशिश की है उसका पालन करना कठिन है। थोड़ी सी हैक की गई, लेकिन आप एक मोनोस्पेस की कोशिश कर सकते हैं / लेबलों के लिए समान रूप से दूरी वाले फ़ॉन्ट के करीब, ताकि उनकी लंबाई अधिक अनुमानित हो। आप तब भी रिक्त स्थान के साथ पैड लेबल कर सकते हैं, यह सुनिश्चित करने के लिए कि पाठ समान लंबाई के करीब है।