Plotly气泡图制作完整教程

Plotly气泡图制作教程

1. 环境准备和包加载

# 加载必要的包
library(plotly)
library(dplyr)
library(RColorBrewer)
library(scales)
library(htmlwidgets)
library(purrr)  
# 设置中文字体(如果需要)
# Sys.setlocale("LC_ALL", "Chinese")

2. 数据生成

我们将创建多个数据集来演示不同类型的气泡图:

# 设置随机种子以确保结果可重现
set.seed(123)

# 数据集1: 国家经济发展数据
countries_data <- data.frame(
  country = c("中国""美国""日本""德国""英国""法国""印度""意大利"
              "巴西""加拿大""俄罗斯""韩国""澳大利亚""西班牙""墨西哥",
              "印度尼西亚""荷兰""沙特阿拉伯""土耳其""瑞士"),
  gdp_per_capita = c(125566529839048532594233041464209934260,
                     889746195112893498051812295659946,
                     42565638323139912781867),
  life_expectancy = c(76.978.984.681.381.382.769.783.5,
                      75.982.472.683.083.483.675.0,
                      71.782.375.177.783.8),
  population = c(1439323776331002651126476461837839426788601165273511,
                 1380004385604618262125594173774215414593446251269185,
                 25499884467547781289327532735236151713487234813871,
                 843390678654622),
  continent = c("亚洲""北美洲""亚洲""欧洲""欧洲""欧洲""亚洲""欧洲",
                "南美洲""北美洲""欧洲""亚洲""大洋洲""欧洲""北美洲",
                "亚洲""欧洲""亚洲""欧洲""欧洲"),
  happiness_score = c(5.1246.9515.8717.0767.0646.5924.0156.387,
                      6.3767.2785.5465.8387.2846.4916.317,
                      5.2407.4496.4065.1327.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(25500200),
  profit_margin = rnorm(25158),
  employees = sample(100:500025),
  industry = sample(c("科技""金融""制造""零售""医疗"), 25replace = TRUE),
  market_cap = rnorm(251000500),
  risk_score = runif(25110)
%>%
  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(3010500),
  sales_volume = sample(100:1000030),
  customer_rating = runif(3025),
  category = sample(c("电子产品""服装""家居""食品""运动"), 30replace = TRUE)
%>%
  mutate(
    revenue = price * sales_volume,
    profit_per_unit = price * runif(300.10.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     中高收入

3. 基础气泡图

3.1 简单气泡图

# 创建基础气泡图
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

4. 高级气泡图 - 颜色控制

4.1 按分类变量着色

# 按大洲着色的气泡图
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 = 2color = '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

4.2 按连续变量着色

# 按幸福指数着色的气泡图
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.5color = '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

5. 大小控制和自定义

5.1 自定义气泡大小

# 公司数据的气泡图 - 自定义大小控制
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 = 2color = '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

5.2 多维度气泡图

# 产品数据的多维度气泡图
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, "<br>类别:", category),
  type = 'scatter',
  mode = 'markers',
  marker = list(
    sizemode = 'diameter',
    sizeref = 2.0 * max(products_data$sales_volume) / (60^2),
    sizemin = 3,
    line = list(width = 1color = '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

6. 交互式功能增强

6.1 动画气泡图

# 创建时间序列数据用于动画
time_series_data <- expand.grid(
  country = c("中国""美国""日本""德国""印度"),
  year = 2015:2022
%>%
  mutate(
    gdp_growth = rnorm(nrow(.), 32),
    investment = runif(nrow(.), 2001000),
    innovation_index = runif(nrow(.), 3080),
    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 = 2color = '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 = 1xanchor = 'right'y = 0yanchor = 'bottom'
  ) %>%
  animation_slider(
    currentvalue = list(prefix = "年份: ")
  )

animated_bubble

7. 高级自定义和样式

7.1 自定义主题气泡图

# 创建深色主题的气泡图
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 = 2color = '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

8. 数据洞察和总结

# 生成数据洞察
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

9. 最佳实践总结
 

www.rdaizuo.com

www.daixie.it.com

www.rcodedaixie.com


专业R语言辅导 | Python编程 | 数据分析 Data analysis | 统计分析 Statistics | 数据挖掘 Data mining | 机器学习 Machine learning | |统计分析 Statistics|STATS 202|STATS 203|STAT 110|STAT 104|STAT 705|STAT 707|STAT4203|STAT4204|STAT4205|STAT4206|STAT 133|STAT 134|STAT 101A|STAT 100A|STAT 581|STAT 520|STAT 521|STAT 4500|STAT 5805|STAT 5806|STAT 4600|STAT30001|STAT3001|STAT3002|STAT3003|STAT3004|STAT3005|STAT3006|STAT5001|STAT5002|STAT5003|STAT5004|

气泡图制作要点:

  1. 数据准备:确保数据质量,处理异常值
  2. 尺寸映射:合理设置sizeref参数控制气泡大小
  3. 颜色选择:使用对比明显的颜色方案
  4. 交互性:添加详细的hover信息
  5. 主题一致性:保持视觉风格统一

常用参数说明:

  • size: 控制气泡大小的变量
  • color: 控制气泡颜色的变量
  • sizeref: 控制气泡大小的缩放比例
  • sizemode: ‘diameter’ 或 ‘area’
  • opacity: 透明度设置
  • marker.line: 气泡边框设置

10. 保存和导出

# 保存为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教程包含了:

shiny 咨询
www.rshinyserver.com
主要特色:

  1. 完整的数据生成:三个不同领域的模拟数据集
  2. 基础到高级:从简单气泡图到复杂交互式图表
  3. 颜色控制:分类变量和连续变量的颜色映射
  4. 大小控制:详细的气泡大小参数设置
  5. 交互功能:动画、子图、hover效果
  6. 样式自定义:深色主题等视觉效果
  7. 实用技巧:最佳实践和参数说明

包含的图表类型:

  • 基础气泡图
  • 按分类着色的气泡图
  • 按连续变量着色的气泡图
  • 多维度气泡图
  • 动画气泡图
  • 子图组合
  • 自定义主题气泡图
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值