Biểu đồ hình tròn trong Python

nhập khẩu cốt truyện. graph_objects khi đi từ cốt truyện. subplots nhập make_subplots fig = make_subplots(rows=2, cols=2, specs=[[{'type'. 'cực'}]*2]*2) hình. add_trace(đi. Phân tán cực( name = "loại góc", r = [5, 4, 2, 4, 5], theta = ["a", "b", "c", "d", "a"], ), 1 . add_trace(đi. Phân cực phân tán ( name = "loại xuyên tâm", r = ["a", "b", "c", "d", "b", "f", "a"], theta = [1, 4, 2, . 5, 1. 5, 6, 5], thetaunit = "radian", ), 1, 2) hình. add_trace(đi. Scatterpolar( name = "angular category (w/category)", r = [5, 4, 2, 4, 5], theta = ["a", "b", "c", "d", "a" . add_trace(đi. Phân cực phân tán ( name = "loại xuyên tâm (w/ loại giảm dần)", r = ["a", "b", "c", "d", "b", "f", "a", "a"] . update_traces(fill='toself') hình. update_layout( polar = dict( radialaxis_angle = -45, angleaxis = dict( direction = "clockwise", period = 6) ), polar2 = dict( radialaxis = dict( angle = 180, tickangle = -180 # để không đánh dấu nhãn . 3141592653589793 ))) hình. buổi bieu diễn()

circular barplot là một biểu đồ thanh, với mỗi thanh được hiển thị dọc theo một vòng tròn thay vì một dòng. Vì vậy, nên hiểu rõ về cách thức hoạt động của barplot trước khi biến nó thành hình tròn. Biểu đồ thanh tròn rất 'bắt mắt' và cho phép sử dụng không gian tốt hơn so với biểu đồ thanh dài thông thường

Dưới đây là ví dụ thể hiện số lượng vũ khí xuất khẩu của top 20 nhà xuất khẩu lớn nhất năm 2017 (thông tin thêm tại đây)

# Libraries
library(tidyverse)
library(hrbrthemes)
library(kableExtra)
options(knitr.table.format = "html")
library(viridis)

# Load dataset from github
data <- read.table("https://raw.githubusercontent.com/holtzy/data_to_viz/master/Example_dataset/7_OneCatOneNum.csv", header=TRUE, sep=",")

# Order data
tmp <- data %>%
  filter(!is.na(Value)) %>%
  arrange(desc(Value)) %>%
  mutate(Country=factor(Country, Country))

# Set a number of 'empty bar'
empty_bar=10

# Add lines to the initial tmpset
to_add = matrix(NA, empty_bar, ncol(tmp))
colnames(to_add) = colnames(tmp)
tmp=rbind(tmp, to_add)
tmp$id=seq(1, nrow(tmp))

# Get the name and the y position of each label
label_tmp=tmp
number_of_bar=nrow(label_tmp)
angle= 90 - 360 * (label_tmp$id-0.5) /number_of_bar     # I substract 0.5 because the letter must have the angle of the center of the bars. Not extreme right(1) or extreme left (0)
label_tmp$hjust<-ifelse( angle < -90, 1, 0)
label_tmp$angle<-ifelse(angle < -90, angle+180, angle)
label_tmp$Country <- gsub("United States", "US", label_tmp$Country)
label_tmp$Country <- paste(label_tmp$Country, " (", label_tmp$Value,")", sep="")

# Make the plot
ggplot(tmp, aes(x=as.factor(id), y=Value)) +       # Note that id is a factor. If x is numeric, there is some space between the first bar
  geom_bar(stat="identity", fill=alpha("#69b3a2", 0.8)) +
  ylim(-7000,13000) +
  theme_minimal() +
  theme(
    axis.text = element_blank(),
    axis.title = element_blank(),
    panel.grid = element_blank(),
    plot.margin = unit(rep(-1,4), "cm") 
  ) +
  coord_polar(start = 0) + 
  geom_text(data=label_tmp, aes(x=id, y=Value+200, label=Country ), color="black", fontface="bold",alpha=0.6, size=2.5, angle= label_tmp$angle, hjust=label_tmp$hjust, inherit.aes = FALSE ) +
  geom_text( aes(x=24, y=8000, label="Who sells more weapons?"), color="black", inherit.aes = FALSE)

Biểu đồ hình tròn trong Python

Ghi chú

  • Ở đây không có thang đo Y nào được hiển thị vì các giá trị chính xác được ghi trên mỗi thanh
  • Thêm đại diện của bộ dữ liệu này có sẵn ở đây, với lời giải thích thêm

Barplot tròn thực sự bắt mắt nhưng làm cho việc đọc sự khác biệt giữa mỗi kích thước thanh trở nên khó khăn hơn. Do đó, biểu đồ thanh tròn chỉ có ý nghĩa nếu bạn có một số lượng lớn thanh để hiển thị và nếu một mẫu rõ ràng xuất hiện

Theo tôi, barplot tròn thậm chí còn thú vị hơn với một biến nhóm. Trong ví dụ sau sử dụng dữ liệu giả, thật dễ dàng để so sánh các nhóm và thực thể thành từng nhóm

# Create dataset
data=data.frame(
  individual=paste( "Mister ", seq(1,60), sep=""),
  group=c( rep('A', 10), rep('B', 30), rep('C', 14), rep('D', 6)) ,
  value=sample( seq(10,100), 60, replace=T)
)
data = data %>% arrange(group, value)

# Set a number of 'empty bar' to add at the end of each group
empty_bar=3
to_add = data.frame( matrix(NA, empty_bar*nlevels(data$group), ncol(data)) )
colnames(to_add) = colnames(data)
to_add$group=rep(levels(data$group), each=empty_bar)
data=rbind(data, to_add)
data=data %>% arrange(group)
data$id=seq(1, nrow(data))
 
# Get the name and the y position of each label
label_data=data
number_of_bar=nrow(label_data)
angle= 90 - 360 * (label_data$id-0.5) /number_of_bar     # I substract 0.5 because the letter must have the angle of the center of the bars. Not extreme right(1) or extreme left (0)
label_data$hjust<-ifelse( angle < -90, 1, 0)
label_data$angle<-ifelse(angle < -90, angle+180, angle)
 
# prepare a data frame for base lines
base_data=data %>% 
  group_by(group) %>% 
  summarize(start=min(id), end=max(id) - empty_bar) %>% 
  rowwise() %>% 
  mutate(title=mean(c(start, end)))
 
# prepare a data frame for grid (scales)
grid_data = base_data
grid_data$end = grid_data$end[ c( nrow(grid_data), 1:nrow(grid_data)-1)] + 1
grid_data$start = grid_data$start - 1
grid_data=grid_data[-1,]
 
# Make the plot
p = ggplot(data, aes(x=as.factor(id), y=value, fill=group)) +       # Note that id is a factor. If x is numeric, there is some space between the first bar
  
  geom_bar(aes(x=as.factor(id), y=value, fill=group), stat="identity", alpha=0.5) +
  
  # Add a val=100/75/50/25 lines. I do it at the beginning to make sur barplots are OVER it.
  geom_segment(data=grid_data, aes(x = end, y = 80, xend = start, yend = 80), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
  geom_segment(data=grid_data, aes(x = end, y = 60, xend = start, yend = 60), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
  geom_segment(data=grid_data, aes(x = end, y = 40, xend = start, yend = 40), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
  geom_segment(data=grid_data, aes(x = end, y = 20, xend = start, yend = 20), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
  
  # Add text showing the value of each 100/75/50/25 lines
  annotate("text", x = rep(max(data$id),4), y = c(20, 40, 60, 80), label = c("20", "40", "60", "80") , color="grey", size=3 , angle=0, fontface="bold", hjust=1) +
  
  geom_bar(aes(x=as.factor(id), y=value, fill=group), stat="identity", alpha=0.5) +
  ylim(-100,120) +
  theme_minimal() +
  theme(
    legend.position = "none",
    axis.text = element_blank(),
    axis.title = element_blank(),
    panel.grid = element_blank(),
    plot.margin = unit(rep(-1,4), "cm") 
  ) +
  coord_polar() + 
  geom_text(data=label_data, aes(x=id, y=value+10, label=individual, hjust=hjust), color="black", fontface="bold",alpha=0.6, size=2.5, angle= label_data$angle, inherit.aes = FALSE ) +
  
  # Add base line information
  geom_segment(data=base_data, aes(x = start, y = -5, xend = end, yend = -5), colour = "black", alpha=0.8, size=0.6 , inherit.aes = FALSE )  +
  geom_text(data=base_data, aes(x = title, y = -18, label=group), hjust=c(1,1,0,0), colour = "black", alpha=0.8, size=4, fontface="bold", inherit.aes = FALSE)
 
p

Biểu đồ hình tròn trong Python


Hầu hết các biến thể được trình bày cho barplot rõ ràng là có sẵn cho barplot tròn. Chẳng hạn, bạn có thể nhóm biến của mình và xếp nhóm để nhận được một stacked circular barplot

# Create dataset
data=data.frame(
  individual=paste( "Mister ", seq(1,60), sep=""),
  group=c( rep('A', 10), rep('B', 30), rep('C', 14), rep('D', 6)) ,
  value1=sample( seq(10,100), 60, replace=T),
  value2=sample( seq(10,100), 60, replace=T),
  value3=sample( seq(10,100), 60, replace=T)
)
 
# Transform data in a tidy format (long format)
data = data %>% gather(key = "observation", value="value", -c(1,2)) 
 
# Set a number of 'empty bar' to add at the end of each group
empty_bar=2
nObsType=nlevels(as.factor(data$observation))
to_add = data.frame( matrix(NA, empty_bar*nlevels(data$group)*nObsType, ncol(data)) )
colnames(to_add) = colnames(data)
to_add$group=rep(levels(data$group), each=empty_bar*nObsType )
data=rbind(data, to_add)
data=data %>% arrange(group, individual)
data$id=rep( seq(1, nrow(data)/nObsType) , each=nObsType)
 
# Get the name and the y position of each label
label_data= data %>% group_by(id, individual) %>% summarize(tot=sum(value))
number_of_bar=nrow(label_data)
angle= 90 - 360 * (label_data$id-0.5) /number_of_bar     # I substract 0.5 because the letter must have the angle of the center of the bars. Not extreme right(1) or extreme left (0)
label_data$hjust<-ifelse( angle < -90, 1, 0)
label_data$angle<-ifelse(angle < -90, angle+180, angle)
 
# prepare a data frame for base lines
base_data=data %>% 
  group_by(group) %>% 
  summarize(start=min(id), end=max(id) - empty_bar) %>% 
  rowwise() %>% 
  mutate(title=mean(c(start, end)))
 
# prepare a data frame for grid (scales)
grid_data = base_data
grid_data$end = grid_data$end[ c( nrow(grid_data), 1:nrow(grid_data)-1)] + 1
grid_data$start = grid_data$start - 1
grid_data=grid_data[-1,]
 
# Make the plot
p = ggplot(data) +      
  
  # Add the stacked bar
  geom_bar(aes(x=as.factor(id), y=value, fill=observation), stat="identity", alpha=0.5) +
  scale_fill_viridis(discrete=TRUE) +
  
  # Add a val=100/75/50/25 lines. I do it at the beginning to make sur barplots are OVER it.
  geom_segment(data=grid_data, aes(x = end, y = 0, xend = start, yend = 0), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
  geom_segment(data=grid_data, aes(x = end, y = 50, xend = start, yend = 50), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
  geom_segment(data=grid_data, aes(x = end, y = 100, xend = start, yend = 100), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
  geom_segment(data=grid_data, aes(x = end, y = 150, xend = start, yend = 150), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
  geom_segment(data=grid_data, aes(x = end, y = 200, xend = start, yend = 200), colour = "grey", alpha=1, size=0.3 , inherit.aes = FALSE ) +
  
  # Add text showing the value of each 100/75/50/25 lines
  annotate("text", x = rep(max(data$id),5), y = c(0, 50, 100, 150, 200), label = c("0", "50", "100", "150", "200") , color="grey", size=2 , angle=0, fontface="bold", hjust=1) +
  
  ylim(-150,max(label_data$tot, na.rm=T)) +
  theme_minimal() +
  theme(
    legend.position = "none",
    axis.text = element_blank(),
    axis.title = element_blank(),
    panel.grid = element_blank(),
    plot.margin = unit(rep(-1,4), "cm") 
  ) +
  coord_polar() +
  
  # Add labels on top of each bar
  geom_text(data=label_data, aes(x=id, y=tot+10, label=individual, hjust=hjust), color="black", fontface="bold",alpha=0.6, size=1, angle= label_data$angle, inherit.aes = FALSE ) +
  
  # Add base line information
  geom_segment(data=base_data, aes(x = start, y = -5, xend = end, yend = -5), colour = "black", alpha=0.8, size=0.6 , inherit.aes = FALSE )  +
  geom_text(data=base_data, aes(x = title, y = -18, label=group), hjust=c(1,1,0,0), colour = "black", alpha=0.8, size=4, fontface="bold", inherit.aes = FALSE)
p

Biểu đồ hình tròn trong Python


  • Tỷ lệ vòng trong phải cực lớn (>1/2). Mặt khác, các thanh rất lệch như trong ví dụ tiếp theo. Theo tôi điều này bóp méo thực tế. những thanh lớn nhất trông thậm chí còn lớn hơn. Bạn có thể đọc thêm về điều đó trong bài viết chuyên dụng

# Create dataset
data=data.frame(
  individual=paste( "Mister ", seq(1,30), sep=""),
  group=c( rep('A', 10), rep('C', 14), rep('D', 6)) ,
  value=sample( seq(10,100), 30, replace=T)
)
data = data %>% arrange(group, value)

# Set a number of 'empty bar' to add at the end of each group
empty_bar=1
to_add = data.frame( matrix(NA, empty_bar*nlevels(data$group), ncol(data)) )
colnames(to_add) = colnames(data)
to_add$group=rep(levels(data$group), each=empty_bar)
data=rbind(data, to_add)
data=data %>% arrange(group)
data$id=seq(1, nrow(data))
 
# Get the name and the y position of each label
label_data=data
number_of_bar=nrow(label_data)
angle= 90 - 360 * (label_data$id-0.5) /number_of_bar     # I substract 0.5 because the letter must have the angle of the center of the bars. Not extreme right(1) or extreme left (0)
label_data$hjust<-ifelse( angle < -90, 1, 0)
label_data$angle<-ifelse(angle < -90, angle+180, angle)
 

# Make the plot
p = ggplot(data, aes(x=as.factor(id), y=value, fill=group)) +       # Note that id is a factor. If x is numeric, there is some space between the first bar
  
  geom_bar(aes(x=as.factor(id), y=value, fill=group), stat="identity", alpha=0.5) +
  ylim(-10,120) +
  theme_minimal() +
  theme(
    legend.position = "none",
    axis.text = element_blank(),
    axis.title = element_blank(),
    panel.grid = element_blank(),
    plot.margin = unit(rep(-1,4), "cm") 
  ) +
  coord_polar() + 
  geom_text(data=label_data, aes(x=id, y=value+10, label=individual, hjust=hjust), color="black", fontface="bold",alpha=0.6, size=2.5, angle= label_data$angle, inherit.aes = FALSE ) 
  
p

Biểu đồ hình tròn trong Python

  • Chỉ hoạt động nếu bạn có nhiều cấp độ để hiển thị (> ~40) và một mẫu rõ ràng
  • Tiếp tục hiển thị trục Y dọc theo vòng tròn
  • Đặt hàng thanh của bạn. Nếu các mức của biến phân loại của bạn không có thứ tự rõ ràng, hãy sắp xếp các thanh theo giá trị của chúng
  • Một số giá trị cho mỗi nhóm? . Ngay cả với các thanh lỗi, nó ẩn thông tin và các loại đồ họa khác như boxplot hoặc violin sẽ phù hợp hơn nhiều


Phòng trưng bày biểu đồ R và Python là 2 trang web cung cấp hàng trăm ví dụ về biểu đồ, luôn cung cấp mã có thể lặp lại. Nhấp vào nút bên dưới để xem cách tạo biểu đồ bạn cần bằng ngôn ngữ lập trình yêu thích của bạn

Thư viện biểu đồ R


Bất kỳ suy nghĩ về điều này?

một barplot tròn là gì?

Biểu đồ thanh tròn là biểu đồ trong đó mỗi thanh được hiển thị dọc theo một vòng tròn thay vì một đường thẳng . Ở đây không có thang đo Y nào được hiển thị vì các giá trị chính xác được ghi trên mỗi thanh cũng có thể được biểu thị khi tương tác với biểu đồ.

Biểu đồ cột xuyên tâm là gì?

Biểu đồ cột xuyên tâm . Loại biểu đồ này vẽ các thanh trên hệ tọa độ cực . Các vòng tròn đồng tâm được sử dụng cho thang giá trị, trong khi các đường phân chia xuyên tâm (các đường kéo dài từ tâm) được sử dụng để vẽ từng loại.