Plotly气泡图制作完整教程
数据可视化教程
2025-06-25
Table of Contents
# 加载必要的包library(plotly)library(dplyr)library(RColorBrewer)library(scales)library(htmlwidgets)library(purrr) # 设置中文字体(如果需要)# Sys.setlocale("LC_ALL", "Chinese")
我们将创建多个数据集来演示不同类型的气泡图:
# 设置随机种子以确保结果可重现set.seed(123)# 数据集1: 国家经济发展数据countries_data <- data.frame( country = c("中国", "美国", "日本", "德国", "英国", "法国", "印度", "意大利", "巴西", "加拿大", "俄罗斯", "韩国", "澳大利亚", "西班牙", "墨西哥", "印度尼西亚", "荷兰", "沙特阿拉伯", "土耳其", "瑞士"), gdp_per_capita = c(12556, 65298, 39048, 53259, 42330, 41464, 2099, 34260, 8897, 46195, 11289, 34980, 51812, 29565, 9946, 4256, 56383, 23139, 9127, 81867), life_expectancy = c(76.9, 78.9, 84.6, 81.3, 81.3, 82.7, 69.7, 83.5, 75.9, 82.4, 72.6, 83.0, 83.4, 83.6, 75.0, 71.7, 82.3, 75.1, 77.7, 83.8), population = c(1439323776, 331002651, 126476461, 83783942, 67886011, 65273511, 1380004385, 60461826, 212559417, 37742154, 145934462, 51269185, 25499884, 46754778, 128932753, 273523615, 17134872, 34813871, 84339067, 8654622), continent = c("亚洲", "北美洲", "亚洲", "欧洲", "欧洲", "欧洲", "亚洲", "欧洲", "南美洲", "北美洲", "欧洲", "亚洲", "大洋洲", "欧洲", "北美洲", "亚洲", "欧洲", "亚洲", "欧洲", "欧洲"), happiness_score = c(5.124, 6.951, 5.871, 7.076, 7.064, 6.592, 4.015, 6.387, 6.376, 7.278, 5.546, 5.838, 7.284, 6.491, 6.317, 5.240, 7.449, 6.406, 5.132, 7.560)) %>% mutate( # 将人口转换为百万为单位,便于可视化 population_millions =population / 1000000, # 创建GDP分类 gdp_category = case_when(gdp_per_capita >= 50000 ~ "高收入",gdp_per_capita >= 20000 ~ "中高收入",gdp_per_capita >= 5000 ~ "中等收入", TRUE ~ "低收入" ) )# 数据集2: 公司业绩数据companies_data <- data.frame( company = paste0("公司", LETTERS[1:25]), revenue = rnorm(25, 500, 200), profit_margin = rnorm(25, 15, 8), employees = sample(100:5000, 25), industry = sample(c("科技", "金融", "制造", "零售", "医疗"), 25, replace = TRUE), market_cap = rnorm(25, 1000, 500), risk_score = runif(25, 1, 10)) %>% mutate( revenue = pmax(revenue, 50), # 确保收入为正 profit_margin = pmax(profit_margin, -5), # 利润率最低-5% market_cap = pmax(market_cap, 100), # 确保市值为正 performance = case_when(profit_margin >= 20 ~ "优秀",profit_margin >= 10 ~ "良好",profit_margin >= 0 ~ "一般", TRUE ~ "较差" ) )# 数据集3: 产品销售数据products_data <- data.frame( product = paste0("产品", 1:30), price = runif(30, 10, 500), sales_volume = sample(100:10000, 30), customer_rating = runif(30, 2, 5), category = sample(c("电子产品", "服装", "家居", "食品", "运动"), 30, replace = TRUE)) %>% mutate( revenue =price * sales_volume, profit_per_unit =price * runif(30, 0.1, 0.4), satisfaction_level = case_when(customer_rating >= 4.5 ~ "非常满意",customer_rating >= 4.0 ~ "满意",customer_rating >= 3.5 ~ "一般", TRUE ~ "不满意" ) )# 显示数据概览head(countries_data)
## country gdp_per_capita life_expectancy population continent happiness_score## 1中国 12556 76.9 1439323776 亚洲 5.124## 2美国 65298 78.9 331002651 北美洲 6.951## 3日本 39048 84.6 126476461 亚洲 5.871## 4德国 53259 81.3 83783942 欧洲 7.076## 5英国 42330 81.3 67886011 欧洲 7.064## 6法国 41464 82.7 65273511 欧洲 6.592## population_millions gdp_category## 1 1439.32378中等收入## 2 331.00265高收入## 3 126.47646中高收入## 4 83.78394高收入## 5 67.88601中高收入## 6 65.27351中高收入
# 创建基础气泡图basic_bubble <- plot_ly( data = countries_data, x = ~gdp_per_capita, y = ~life_expectancy, size = ~population_millions, text = ~country, type = 'scatter', mode = 'markers', hovertemplate = paste( '<b>%{text}</b><br>', 'GDP per capita: $%{x:,.0f}<br>', 'Life expectancy: %{y:.1f} years<br>', 'Population: %{marker.size:.1f}M<br>', '<extra></extra>' )) %>% layout( title = list(text = "世界各国GDP、预期寿命与人口关系", font = list(size = 16)), xaxis = list(title = "人均GDP (美元)"), yaxis = list(title = "预期寿命 (年)"), showlegend = FALSE )basic_bubble
# 按大洲着色的气泡图continent_bubble <- plot_ly( data = countries_data, x = ~gdp_per_capita, y = ~life_expectancy, size = ~population_millions, color = ~continent, colors = RColorBrewer::brewer.pal(6, "Set3"), text = ~country, type = 'scatter', mode = 'markers', marker = list( sizemode = 'diameter', sizeref = 2.0 * max(countries_data$population_millions) / (40^2), line = list(width = 2, color = 'rgba(255, 255, 255, 0.8)') ), hovertemplate = paste( '<b>%{text}</b><br>', 'GDP per capita: $%{x:,.0f}<br>', 'Life expectancy: %{y:.1f} years<br>', 'Population: %{marker.size:.1f}M<br>', 'Continent: %{marker.color}<br>', '<extra></extra>' )) %>% layout( title = list(text = "按大洲分类的气泡图", font = list(size = 16)), xaxis = list(title = "人均GDP (美元)", type = "log"), yaxis = list(title = "预期寿命 (年)"), legend = list(title = list(text = "大洲")) )continent_bubble
# 按幸福指数着色的气泡图happiness_bubble <- plot_ly( data = countries_data, x = ~gdp_per_capita, y = ~life_expectancy, size = ~population_millions, color = ~happiness_score, colors = colorRamp(c("red", "yellow", "green")), text = ~country, type = 'scatter', mode = 'markers', marker = list( sizemode = 'diameter', sizeref = 2.0 * max(countries_data$population_millions) / (40^2), line = list(width = 1.5, color = 'rgba(0, 0, 0, 0.3)'), colorbar = list(title = "幸福指数") ), hovertemplate = paste( '<b>%{text}</b><br>', 'GDP per capita: $%{x:,.0f}<br>', 'Life expectancy: %{y:.1f} years<br>', 'Population: %{marker.size:.1f}M<br>', 'Happiness Score: %{marker.color:.2f}<br>', '<extra></extra>' )) %>% layout( title = list(text = "按幸福指数着色的气泡图", font = list(size = 16)), xaxis = list(title = "人均GDP (美元)"), yaxis = list(title = "预期寿命 (年)") )happiness_bubble
# 公司数据的气泡图 - 自定义大小控制company_bubble <- plot_ly( data = companies_data, x = ~revenue, y = ~profit_margin, size = ~employees, color = ~industry, colors = viridis::viridis(5), text = ~company, type = 'scatter', mode = 'markers', marker = list( sizemode = 'diameter', sizeref = 2.0 * max(companies_data$employees) / (50^2), sizemin = 4, line = list(width = 2, color = 'rgba(255, 255, 255, 0.9)'), opacity = 0.8 ), hovertemplate = paste( '<b>%{text}</b><br>', 'Revenue: $%{x:.1f}M<br>', 'Profit Margin: %{y:.1f}%<br>', 'Employees: %{marker.size:,.0f}<br>', 'Industry: %{marker.color}<br>', '<extra></extra>' )) %>% layout( title = list(text = "公司收入、利润率与员工数量关系", font = list(size = 16)), xaxis = list(title = "收入 (百万美元)"), yaxis = list(title = "利润率 (%)"), legend = list(title = list(text = "行业")) )company_bubble
# 产品数据的多维度气泡图product_bubble <- plot_ly( data = products_data, x = ~price, y = ~customer_rating, size = ~sales_volume, color = ~revenue, colors = colorRamp(c("blue", "lightblue", "yellow", "orange", "red")), text = ~paste("产品:", product, "
类别:", category), type = 'scatter', mode = 'markers', marker = list( sizemode = 'diameter', sizeref = 2.0 * max(products_data$sales_volume) / (60^2), sizemin = 3, line = list(width = 1, color = 'rgba(0, 0, 0, 0.5)'), opacity = 0.7, colorbar = list( title = "收入", titleside = "right" ) ), hovertemplate = paste( '%{text}<br>', 'Price: $%{x:.2f}<br>', 'Rating: %{y:.2f}/5<br>', 'Sales Volume: %{marker.size:,.0f}<br>', 'Revenue: $%{marker.color:,.0f}<br>', '<extra></extra>' )) %>% layout( title = list(text = "产品价格、评分、销量与收入关系", font = list(size = 16)), xaxis = list(title = "价格 (美元)", type = "log"), yaxis = list(title = "客户评分 (1-5分)") )product_bubble
# 创建时间序列数据用于动画time_series_data <- expand.grid( country = c("中国", "美国", "日本", "德国", "印度"), year = 2015:2022) %>% mutate( gdp_growth = rnorm(nrow(.), 3, 2), investment = runif(nrow(.), 200, 1000), innovation_index = runif(nrow(.), 30, 80), gdp_growth = pmax(gdp_growth, -5) # 确保增长率不会太低 )# 创建动画气泡图animated_bubble <-time_series_data %>% plot_ly( x = ~investment, y = ~gdp_growth, size = ~innovation_index, color = ~country, frame = ~year, text = ~country, type = 'scatter', mode = 'markers', marker = list( sizemode = 'diameter', sizeref = 2.0 * max(time_series_data$innovation_index) / (40^2), line = list(width = 2, color = 'rgba(255, 255, 255, 0.8)') ), hovertemplate = paste( '<b>%{text}</b><br>', 'Investment: $%{x:.0f}B<br>', 'GDP Growth: %{y:.1f}%<br>', 'Innovation Index: %{marker.size:.1f}<br>', '<extra></extra>' )) %>% layout( title = list(text = "国家投资、GDP增长与创新指数 (2015-2022)", font = list(size = 16)), xaxis = list(title = "投资 (十亿美元)"), yaxis = list(title = "GDP增长率 (%)"), legend = list(title = list(text = "国家"))) %>% animation_opts( frame = 800, transition = 400, easing = "elastic", redraw = FALSE) %>% animation_button( x = 1, xanchor = 'right', y = 0, yanchor = 'bottom') %>% animation_slider( currentvalue = list(prefix = "年份: ") )animated_bubble
# 创建深色主题的气泡图dark_theme_bubble <- plot_ly( data = countries_data, x = ~gdp_per_capita, y = ~happiness_score, size = ~population_millions, color = ~continent, colors = c("#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#FFEAA7", "#DDA0DD"), text = ~country, type = 'scatter', mode = 'markers', marker = list( sizemode = 'diameter', sizeref = 2.0 * max(countries_data$population_millions) / (50^2), line = list(width = 2, color = 'rgba(255, 255, 255, 0.3)'), opacity = 0.8 )) %>% layout( title = list( text = "GDP与幸福指数关系 - 深色主题", font = list(color = "white", size = 18) ), xaxis = list( title = "人均GDP (美元)", gridcolor = 'rgba(255,255,255,0.1)', color = "white" ), yaxis = list( title = "幸福指数", gridcolor = 'rgba(255,255,255,0.1)', color = "white" ), plot_bgcolor = 'rgba(0,0,0,0.9)', paper_bgcolor = 'rgba(0,0,0,0.9)', font = list(color = "white"), legend = list( font = list(color = "white"), title = list(text = "大洲", font = list(color = "white")) ) )dark_theme_bubble
# 生成数据洞察cat("=== 数据洞察总结 ===\n")
## === 数据洞察总结 ===
cat("国家数据分析:\n")
## 国家数据分析:
cat("- 最高人均GDP国家:", countries_data$country[which.max(countries_data$gdp_per_capita)], "\n")
## - 最高人均GDP国家: 瑞士
cat("- 预期寿命最长国家:", countries_data$country[which.max(countries_data$life_expectancy)], "\n")
## - 预期寿命最长国家: 日本
cat("- 人口最多国家:", countries_data$country[which.max(countries_data$population)], "\n")
## - 人口最多国家: 中国
cat("- 最幸福国家:", countries_data$country[which.max(countries_data$happiness_score)], "\n\n")
## - 最幸福国家: 瑞士
cat("公司数据分析:\n")
## 公司数据分析:
cat("- 收入最高公司:", companies_data$company[which.max(companies_data$revenue)], "\n")
## - 收入最高公司: 公司P
cat("- 利润率最高公司:", companies_data$company[which.max(companies_data$profit_margin)], "\n")
## - 利润率最高公司: 公司S
cat("- 员工最多公司:", companies_data$company[which.max(companies_data$employees)], "\n\n")
## - 员工最多公司: 公司H
# 相关性分析cat("相关性分析:\n")
## 相关性分析:
cat("GDP与预期寿命相关系数:", round(cor(countries_data$gdp_per_capita, countries_data$life_expectancy), 3), "\n")
## GDP与预期寿命相关系数: 0.754
cat("GDP与幸福指数相关系数:", round(cor(countries_data$gdp_per_capita, countries_data$happiness_score), 3), "\n")
## GDP与幸福指数相关系数: 0.822
1. 数据准备:确保数据质量,处理异常值
2. 尺寸映射:合理设置sizeref参数控制气泡大小
3. 颜色选择:使用对比明显的颜色方案
4. 交互性:添加详细的hover信息
5. 主题一致性:保持视觉风格统一
· size: 控制气泡大小的变量
· color: 控制气泡颜色的变量
· sizeref: 控制气泡大小的缩放比例
· sizemode: ‘diameter’ 或 ‘area’
· opacity: 透明度设置
· marker.line: 气泡边框设置
# 保存为HTML文件htmlwidgets::saveWidget(continent_bubble, "bubble_chart.html", selfcontained = TRUE)# 保存为静态图片 (需要安装kaleido包)# install.packages("reticulate")# reticulate::py_install("kaleido")# plotly::save_image(continent_bubble, "bubble_chart.png", width = 1200, height = 800)
这个完整的R Markdown教程包含了:
**专业R语言辅导 | Python编程 | 数据分析 Data analysis | 统计分析 Statistics | 数据挖掘 Data mining | 机器学习 Machine learning | 留学生作业代做代写|6.864|9.520|6-867|CS229|CS231n|CS236|CS224n|STATS 202|STATS 203|STAT 110|STAT 104|CS109|BIOS221|10-701|10-605|10-607|10-601|10-603|10-604|STAT 705|STAT 707|COMS4771|COMS5771|COMS5733|COMS4733|STAT4203|STAT4204|STAT4205|STAT4206|STAT 133|STAT 134|DATA C88|CS 265|STAT 101A|STAT 100A|CS273A|CSE250A|COGS118A|CS-GY.6923|BUSF-GB.2397|CS 542|STAT 581|MLMI 201|MLMI 202|COMP0087|COMP0088|COMP01011|COMP3008|INFR11136|INFR11218|DATA1001|CSC311H1|CSC411|CSC413|CSC414|CSC412|STA302|STA2453H|STAT 302|DSCI511|DSCI512|DSCI513|DSCI514|STAT 540|STAT 541|CPSC 587|STAT 517|COMP 551|COMP 520|STAT 520|STAT 521|STAT 4500|STAT 5805|STAT 5806|STAT 4600|COMP5805|COMP90051|COMP90053|COMP90054|COMP90057|MATH90010|MATH90011|MATH90012|STAT30001|COMP1730|STAT3001|STAT3002|STAT3003|STAT3004|STAT3005|STAT3006|MATH3001|COMP5311|COMP5312|COMP5313|COMP5314|COMP5315|COMP5316|COMP5317|COMP5318|STAT5001|STAT5002|STAT5003|STAT5004|FIT5097|FIT5098|FIT5099|FIT5100|MTH5001|MTH5002|MTH5003**
咨询r语言问题
www.rdaizuo.com
www.daixie.it.com
1. 完整的数据生成:三个不同领域的模拟数据集
2. 基础到高级:从简单气泡图到复杂交互式图表
3. 颜色控制:分类变量和连续变量的颜色映射
4. 大小控制:详细的气泡大小参数设置
5. 交互功能:动画、子图、hover效果
6. 样式自定义:深色主题等视觉效果
7. 实用技巧:最佳实践和参数说明
· 基础气泡图
· 按分类着色的气泡图
· 按连续变量着色的气泡图
· 多维度气泡图
· 动画气泡图
· 子图组合
· 自定义主题气泡图