ggplot绘制带误差棒、置信区间的柱状图,并调整颜色为渐变

这篇博客介绍了如何利用ggplot2库在R中绘制带有置信区间的柱状图,包括如何控制柱状图的宽度、间距以及实现颜色的渐变效果。通过示例代码详细解释了geom_bar、geom_errorbar和scale_fill_gradient等函数的用法,以帮助读者定制自己的柱状图。

ggplot绘制带误差棒、置信区间的柱状图,并调整颜色为渐变

在这里插入图片描述

简单绘制柱状图

要在ggplot中绘制带有置信区间的柱状图,你可以使用geom_bar和geom_errorbar函数来完成。下面是一个示例代码:

library(ggplot2)

# 创建一个示例数据集
data <- data.frame(
  category = c("A", "B", "C"),
  value 
import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import FancyBboxPatch, Circle, Rectangle import matplotlib.patches as patches from matplotlib.offsetbox import OffsetImage, AnnotationBbox # 设置中文字体(如果需要显示中文) plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签 plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号 # 创建图形和子图布局 fig = plt.figure(figsize=(16, 8)) gs = fig.add_gridspec(2, 2, width_ratios=[1, 1], height_ratios=[3, 1]) # 左上方主图:愈合动力学曲线 ax_main = fig.add_subplot(gs[0, 0]) # 左下方:k值柱状图 ax_inset = fig.add_subplot(gs[1, 0]) # 右侧机理图 ax_mech = fig.add_subplot(gs[:, 1]) # 设置整体背景色 fig.patch.set_facecolor('#f8f9fa') # ==================== 左上方主图:愈合动力学曲线 ==================== # 模拟数据点 time_80 = np.array([0, 5, 10, 15, 20, 25, 30]) # 分钟 wca_80 = np.array([20, 80, 120, 140, 147, 150, 152]) time_120 = np.array([0, 4, 8, 12, 16, 20, 24, 30]) wca_120 = np.array([20, 85, 125, 142, 149, 151, 152, 152]) time_60 = np.array([0, 10, 20, 30, 40, 50, 60]) wca_60 = np.array([20, 45, 75, 105, 125, 140, 148]) # 25°C数据(时间转换为分钟) time_25 = np.array([0, 360, 720, 1080, 1440]) # 分钟 (0, 6, 12, 18, 24小时) wca_25 = np.array([20, 90, 125, 142, 150]) # 绘制曲线 ax_main.plot(time_80, wca_80, 'r-', linewidth=3, label='80°C', marker='o', markersize=6) ax_main.plot(time_120, wca_120, 'm--', linewidth=2, label='120°C', marker='s', markersize=5) ax_main.plot(time_60, wca_60, 'b-', linewidth=2, label='60°C', marker='^', markersize=5) ax_main.plot(time_25, wca_25, 'g-', linewidth=2, label='25°C', marker='d', markersize=5) # 设置坐标轴 ax_main.set_xlabel('时间 (分钟)', fontsize=12) ax_main.set_ylabel('水接触角 (WCA, °)', fontsize=12) ax_main.set_ylim(0, 160) ax_main.set_xlim(0, 1500) # 扩展到24小时(1440分钟) ax_main.grid(True, alpha=0.3) # 添加第二个x轴(小时单位) ax2 = ax_main.twiny() ax2.set_xlim(0, 25) # 0-25小时 ax2.set_xlabel('时间 (小时)', fontsize=12) ax2.spines['top'].set_position(('outward', 40)) # 标注阶段 ax_main.axvline(x=15, color='gray', linestyle=':', alpha=0.7) ax_main.axvline(x=360, color='gray', linestyle=':', alpha=0.7) # 6小时 ax_main.text(7, 40, '快速恢复阶段\n(0-15min @80-120°C\n0-6h @25°C)', fontsize=9, bbox=dict(boxstyle="round,pad=0.3", fc="lightblue", alpha=0.7)) ax_main.text(200, 140, '缓慢稳定阶段\n(15-30min @80-120°C\n6-24h @25°C)', fontsize=9, bbox=dict(boxstyle="round,pad=0.3", fc="lightgreen", alpha=0.7)) ax_main.legend(loc='lower right', fontsize=10) # ==================== 左下方:k值柱状图 ==================== temperatures = ['25°C', '60°C', '80°C', '120°C'] k_values = [0.004, 0.048, 0.12, 0.13] colors = ['green', 'blue', 'red', 'magenta'] bars = ax_inset.bar(temperatures, k_values, color=colors, alpha=0.7) ax_inset.set_ylabel('愈合速率常数 k (min⁻¹)', fontsize=10) ax_inset.set_ylim(0, 0.14) # 在柱子上添加数值和倍数关系 for i, (bar, k) in enumerate(zip(bars, k_values)): height = bar.get_height() ax_inset.text(bar.get_x() + bar.get_width()/2., height + 0.005, f'{k:.3f}', ha='center', va='bottom', fontsize=9) if i == 2: # 80°C柱子 ax_inset.text(bar.get_x() + bar.get_width()/2., height/2, '最大值', ha='center', va='center', fontsize=9, bbox=dict(boxstyle="round,pad=0.2", fc="yellow", alpha=0.7)) # 添加倍数关系标注 ax_inset.annotate('', xy=(1, 0.12), xytext=(1, 0.048), arrowprops=dict(arrowstyle='<->', color='black', lw=1.5)) ax_inset.text(1.2, 0.08, '2.5×', fontsize=10, fontweight='bold') ax_inset.annotate('', xy=(0, 0.12), xytext=(0, 0.004), arrowprops=dict(arrowstyle='<->', color='black', lw=1.5)) ax_inset.text(0.2, 0.06, '30×', fontsize=10, fontweight='bold') # ==================== 右侧:愈合机理示意图 ==================== # 设置右侧子图范围 ax_mech.set_xlim(0, 10) ax_mech.set_ylim(0, 8) ax_mech.axis('off') # 不显示坐标轴 # 绘制三个状态 states = [ {"x": 1, "title": "状态 I: 初始损伤", "wca": "WCA ≈ 20°", "desc": "表面被划伤,亲水颗粒暴露"}, {"x": 4, "title": "阶段 1: 快速恢复", "wca": "WCA = 130°-140°", "desc": "PDMS链快速迁移\n恢复低表面能层"}, {"x": 7, "title": "阶段 2: 缓慢稳定", "wca": "WCA = 150°-153°", "desc": "颗粒重排形成\n微纳分级粗糙结构"} ] # 绘制表面和颗粒 for i, state in enumerate(states): x = state["x"] # 表面基线 ax_mech.plot([x-0.8, x+0.8], [2, 2], 'k-', linewidth=2) # 划痕(只在状态I显示) if i == 0: ax_mech.plot([x-0.2, x+0.2], [2.1, 1.9], 'r-', linewidth=3) # 颗粒(用圆圈表示) n_particles = 15 for j in range(n_particles): px = x - 0.7 + (j % 5) * 0.35 py = 2.2 + (j // 5) * 0.3 # 状态I:亲水颗粒(空心) if i == 0: circle = plt.Circle((px, py), 0.08, fill=False, edgecolor='blue', linewidth=1.5) # 状态2和3:PDMS覆盖的颗粒(实心) else: circle = plt.Circle((px, py), 0.08, facecolor='orange', alpha=0.7) ax_mech.add_patch(circle) # PDMS链(状态2和3) if i > 0: for j in range(8): px = x - 0.6 + j * 0.2 # 绘制弯曲的PDMS链 t = np.linspace(0, 3, 50) y_curve = 1.5 + 0.3 * np.sin(t + j * 0.5) x_curve = px + 0.01 * t ax_mech.plot(x_curve, y_curve, 'orange', linewidth=1.5, alpha=0.8) # 状态3:更粗糙的结构(用更大的起伏表示) if i == 2: roughness_x = np.linspace(x-0.8, x+0.8, 20) roughness_y = 2 + 0.15 * np.sin(8 * roughness_x) ax_mech.plot(roughness_x, roughness_y, 'b-', linewidth=1, alpha=0.6) # 添加状态标题和说明 ax_mech.text(x, 6.5, state["title"], ha='center', fontsize=12, fontweight='bold') ax_mech.text(x, 6, state["wca"], ha='center', fontsize=11, bbox=dict(boxstyle="round,pad=0.3", fc="lightyellow", alpha=0.8)) ax_mech.text(x, 5.5, state["desc"], ha='center', fontsize=10, bbox=dict(boxstyle="round,pad=0.3", fc="lightgray", alpha=0.7)) # 添加箭头表示过程 ax_mech.annotate('', xy=(3.2, 4), xytext=(1.8, 4), arrowprops=dict(arrowstyle='->', lw=2, color='red')) ax_mech.annotate('', xy=(6.2, 4), xytext=(4.8, 4), arrowprops=dict(arrowstyle='->', lw=2, color='red')) # 添加水滴示意图 for i, y in enumerate([3.5, 4, 4.5]): # 绘制水滴形状 theta = np.linspace(0, 2*np.pi, 100) r = 0.15 drop_x = 8.5 + r * np.cos(theta) drop_y = y + r * 2 * np.sin(theta) # 椭圆形状更像水滴 ax_mech.fill(drop_x, drop_y, 'lightblue', alpha=0.6) # 添加接触角标注 if i == 0: ax_mech.text(9, y, '亲水', fontsize=9) elif i == 2: ax_mech.text(9, y, '超疏水', fontsize=9) # ==================== 添加整体标题和说明文本框 ==================== plt.suptitle('自愈合超疏水涂层愈合过程与动力学示意图', fontsize=16, fontweight='bold') # 添加说明文本框 text_box = """ 温度选择权衡: • 80°C: 最佳平衡点 - 高愈合效率(k=0.12 min⁻¹)且保持纤维完整性 • 120°C: 速率增益有限(k=0.13 min⁻¹)但可能导致纤维收缩 • 25°C: 无需外部加热,适合现场修复(24h内WCA恢复至150°) """ ax_main.text(0.02, 0.02, text_box, transform=ax_main.transAxes, fontsize=10, bbox=dict(boxstyle="round,pad=0.5", fc="white", alpha=0.8), verticalalignment='bottom') # 调整布局 plt.tight_layout() plt.subplots_adjust(top=0.92, bottom=0.08, left=0.05, right=0.95, hspace=0.3, wspace=0.2) # 保存图片 plt.savefig('self_healing_superhydrophobic_coating.png', dpi=300, bbox_inches='tight') plt.savefig('self_healing_superhydrophobic_coating.pdf', bbox_inches='tight') # 显示图片 plt.show()
09-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sta@ma@brain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值