web-dev-qa-db-ja.com

積み上げパーセント棒グラフのラベルを中央に配置する方法

ニースをプロットしようとしていますstacked percent barchartを使用してggplot2。私はいくつかの資料を読み、ほとんど何とかしてプロットしたい。また、資料を同封しました。1か所で役立つ場合があります。

サマリーデータフレームを作成せずにggplot2で積み上げ棒グラフにラベルを付けるにはどうすればよいですか?

各スタックが合計100%にスケーリングされるスタック型棒グラフを作成

バイナリ係数とラベルのパーセンテージを含むR積み上げパーセンテージバープロット(ggplotを使用)

私の問題は、labelsをバーの真ん中の好きな場所に配置できないことです。 enter image description here

上の図で問題を確認できます-ラベルがひどく見え、互いに重なり合っています。

私が今探しているのは:

  1. バー(エリア)の中央にラベルを配置する方法

  2. すべてのラベルではなく、たとえば10%より大きいラベルをプロットする方法は?

  3. オーバーラップ問題を解決するには?

のために Q 1. @MikeWiseが可能な提案 ソリューション 。しかし、私はまだこの問題に対処できません。

また、再現可能な例、つまりこのグラフをどのようにプロットしたかを示します。

library('plyr')
library('ggplot2')
library('scales')
set.seed(1992)
n=68

Category <- sample(c("Black", "Red", "Blue", "Cyna", "Purple"), n, replace = TRUE, prob = NULL)
Brand <- sample("Brand", n, replace = TRUE, prob = NULL)
Brand <- paste0(Brand, sample(1:5, n, replace = TRUE, prob = NULL))
USD <- abs(rnorm(n))*100

df <- data.frame(Category, Brand, USD)

# Calculate the percentages
df = ddply(df, .(Brand), transform, percent = USD/sum(USD) * 100)


# Format the labels and calculate their positions
df = ddply(df, .(Brand), transform, pos = (cumsum(USD) - 0.5 * USD))

#create Nice labes
df$label = paste0(sprintf("%.0f", df$percent), "%")  



ggplot(df, aes(x=reorder(Brand,USD,
                              function(x)+sum(x)),  y=percent, fill=Category))+
  geom_bar(position = "fill", stat='identity',  width = .7)+
  geom_text(aes(label=label, ymax=100, ymin=0), vjust=0, hjust=0,color = "white",  position=position_fill())+
  coord_flip()+
  scale_y_continuous(labels = percent_format())+
  ylab("")+
  xlab("")
25
AK47

ラベルを中央に配置し、小さなパーセンテージのラベルをプロットしないようにする方法を次に示します。データのもう1つの問題は、色ごとに複数のバーセクションがあることです。代わりに、特定の色のすべてのバーセクションを組み合わせる必要があるようです。以下のコードは、dplyrではなくplyrを使用して、プロット用のデータを設定します。

_library(dplyr)

# Initial data frame   
df <- data.frame(Category, Brand, USD)

# Calculate percentages
df.summary = df %>% group_by(Brand, Category) %>% 
  summarise(USD = sum(USD)) %>%   # Within each Brand, sum all values in each Category
  mutate(percent = USD/sum(USD))
_

Ggplot2バージョン2では、テキストラベルを中央に配置するために座標を計算する必要がなくなりました。代わりに、position=position_stack(vjust=0.5)を使用できます。例えば:

_ggplot(df.summary, aes(x=reorder(Brand, USD, sum), y=percent, fill=Category)) +
  geom_bar(stat="identity", width = .7, colour="black", lwd=0.1) +
  geom_text(aes(label=ifelse(percent >= 0.07, paste0(sprintf("%.0f", percent*100),"%"),"")),
                position=position_stack(vjust=0.5), colour="white") +
  coord_flip() +
  scale_y_continuous(labels = percent_format()) +
  labs(y="", x="")
_

enter image description here


古いバージョンでは、位置を計算する必要があります。 (上記と同じですが、posを定義する追加の行があります):

_# Calculate percentages and label positions
df.summary = df %>% group_by(Brand, Category) %>% 
  summarise(USD = sum(USD)) %>%   # Within each Brand, sum all values in each Category
  mutate(percent = USD/sum(USD),
         pos = cumsum(percent) - 0.5*percent)
_

次に、ifelseステートメントを使用してデータをプロットし、ラベルがプロットされているかどうかを判断します。この場合、7%未満の割合でラベルをプロットすることは避けました。

_ggplot(df.summary, aes(x=reorder(Brand,USD,function(x)+sum(x)), y=percent, fill=Category)) +
  geom_bar(stat='identity',  width = .7, colour="black", lwd=0.1) +
  geom_text(aes(label=ifelse(percent >= 0.07, paste0(sprintf("%.0f", percent*100),"%"),""),
                y=pos), colour="white") +
  coord_flip() +
  scale_y_continuous(labels = percent_format()) +
  labs(y="", x="")
_

enter image description here

36
eipi10

私は例に従って、単純な積み上げ棒グラフにニースラベルを付ける方法を見つけました。役に立つかもしれません。

df <- data.frame(Category, Brand, USD)

# Calculate percentages and label positions
df.summary = df %>% group_by(Brand, Category) %>% 
  summarise(USD = sum(USD)) %>%   # Within each Brand, sum all values in each Category
  mutate( pos = cumsum(USD)-0.5*USD)

ggplot(df.summary, aes(x=reorder(Brand,USD,function(x)+sum(x)), y=USD, fill=Category)) +
  geom_bar(stat='identity',  width = .7, colour="black", lwd=0.1) +
  geom_text(aes(label=ifelse(USD>100,round(USD,0),""),
                y=pos), colour="white") +
  coord_flip()+
  labs(y="", x="")

enter image description here

1
AK47