python pic1:环形图

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from matplotlib.cm import ScalarMappable
from matplotlib.colors import Normalize
from matplotlib.patches import Patch

# ===== 强制中文字体设置 =====
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False

# ========== 1. 读取Excel数据 ==========
file_path = r"D:/趋势图.xlsx"
df = pd.read_excel(file_path, engine='openpyxl')

categories = df["区间"].values
area_before = df["作业前面积"].values
area_after = df["作业后面积"].values

# 清洗标签
clean_categories = []
for label in categories:
    label_str = str(label)
    label_str = label_str.replace('-0.0', '0')
    label_str = label_str.replace('--', '-')
    clean_categories.append(label_str)

# ========== 2. 双环形图 ==========
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 7), subplot_kw=dict(projection='polar'))
fig.suptitle('作业前后面积分布对比', fontsize=18, fontweight='bold', y=0.98)

angles = np.linspace(0, 2 * np.pi, len(categories), endpoint=False).tolist()
angles += angles[:1]

# ===== 统一刻度:0-50,步长5 =====
max_val = 50
yticks = np.arange(0, 51, 5)

# ===== 两边都用蓝色 =====
colors = plt.cm.Blues(np.linspace(0.3, 0.9, len(categories)))

# ----- 左图:作业前面积 -----
data_before = area_before.tolist() + area_before[:1].tolist()
ax1.bar(angles, data_before, width=0.6, color=colors, alpha=0.8, edgecolor='white', linewidth=1)
ax1.set_xticks(angles[:-1])
ax1.set_xticklabels(clean_categories, fontsize=15)
ax1.set_title('作业前面积', fontsize=14, fontweight='bold', pad=15)
ax1.set_ylim(0, max_val)
ax1.set_yticks(yticks)
ax1.set_yticklabels([str(int(y)) for y in yticks], fontsize=12)

# for i, (angle, val) in enumerate(zip(angles[:-1], area_before)):
#     if val > 1:
#         ax1.text(angle, val + 2, f'{val:.1f}', fontsize=8, ha='center', va='center', color='blue')

# ----- 右图:作业后面积 -----
data_after = area_after.tolist() + area_after[:1].tolist()
ax2.bar(angles, data_after, width=0.6, color=colors, alpha=0.8, edgecolor='white', linewidth=1)
ax2.set_xticks(angles[:-1])
ax2.set_xticklabels(clean_categories, fontsize=15)
ax2.set_title('作业后面积', fontsize=14, fontweight='bold', pad=15)
ax2.set_ylim(0, max_val)
ax2.set_yticks(yticks)
ax2.set_yticklabels([str(int(y)) for y in yticks], fontsize=12)

# for i, (angle, val) in enumerate(zip(angles[:-1], area_after)):
#     if val > 1:
#         ax2.text(angle, val + 2, f'{val:.1f}', fontsize=8, ha='center', va='center', color='blue')

# ========== 3. 添加图例(说明外圈是NDVI区间)==========
from matplotlib.patches import Patch

# 创建一个图例,说明外圈标签的含义
legend_elements = [
    Patch(facecolor='none', edgecolor='none', label='外圈 = NDVI区间'),
    Patch(facecolor='#4a9eff', alpha=0.6, edgecolor='white', label='面积值(颜色越深越大)')
]

# 左图图例
ax1.legend(handles=legend_elements, loc='upper center', bbox_to_anchor=(1.2, 1.2), fontsize=10,
           facecolor='white', edgecolor='black', framealpha=0.9)

# 右图图例
ax2.legend(handles=legend_elements, loc='upper center', bbox_to_anchor=(1.2, 1.2), fontsize=10,
           facecolor='white', edgecolor='black', framealpha=0.9)

# ========== 4. 添加颜色条 ==========
norm = Normalize(vmin=0, vmax=50)

cbar1 = fig.colorbar(ScalarMappable(norm=norm, cmap=plt.cm.Blues), ax=ax1, orientation='vertical',
                     pad=0.12, shrink=0.6)
cbar1.set_label('面积值', fontsize=10)

cbar2 = fig.colorbar(ScalarMappable(norm=norm, cmap=plt.cm.Blues), ax=ax2, orientation='vertical',
                     pad=0.12, shrink=0.6)
cbar2.set_label('面积值', fontsize=10)

plt.tight_layout()
plt.show()

图3

 

posted @ 2026-06-21 15:12  SuYue2990  Views(1)  Comments(0)    收藏  举报