|
|
# -*- coding: utf-8 -*-
|
|
|
import matplotlib
|
|
|
|
|
|
matplotlib.use("agg")
|
|
|
import matplotlib.pyplot as plt
|
|
|
import numpy as np
|
|
|
import os
|
|
|
from datetime import datetime
|
|
|
from matplotlib.font_manager import FontProperties
|
|
|
|
|
|
# # 数据
|
|
|
# data = {
|
|
|
# "停电用户\n(万户)": {"昨天": 200.87, "今天": 132.59},
|
|
|
# "过载配变\n(台)": {"昨天": 126, "今天": 119},
|
|
|
# "95598供电类投诉\n(条)": {"昨天": 18, "今天": 12},
|
|
|
# "涉电力供应类舆情风险信息\n(条)": {"昨天": 79, "今天": 40}
|
|
|
# }
|
|
|
|
|
|
|
|
|
def plot_electricity_comparison(year, month, day, data):
|
|
|
year = int(year)
|
|
|
month = int(month)
|
|
|
day = int(day)
|
|
|
|
|
|
# # 设置中文字体
|
|
|
plt.rcParams["font.sans-serif"] = [
|
|
|
"Microsoft YaHei"
|
|
|
] # 字体设置,用来正常显示中文标签
|
|
|
plt.rcParams["axes.unicode_minus"] = False # 用来正常显示负号
|
|
|
|
|
|
# # 创建一个大图形,1行4列的子图布局
|
|
|
# fig, axs = plt.subplots(1, 4, figsize=(8, 4)) # 1行4列的子图布局
|
|
|
|
|
|
# 定义横轴标签
|
|
|
categories = ["昨天", "今天"]
|
|
|
x = np.arange(len(categories))
|
|
|
|
|
|
# 计算变化百分比
|
|
|
def calculate_change_percentage(yesterday, today):
|
|
|
return ((today - yesterday) / yesterday) * 100
|
|
|
|
|
|
# 检查数据完整性并过滤掉不完整的数据
|
|
|
valid_data = {}
|
|
|
for title, values in data.items():
|
|
|
if "昨天" in values and "今天" in values:
|
|
|
if values["昨天"] is not None and values["今天"] is not None:
|
|
|
valid_data[title] = values
|
|
|
|
|
|
# 如果没有有效的数据,返回 None 或其他指示
|
|
|
if not valid_data:
|
|
|
return None # 没有有效的数据,不生成图片
|
|
|
|
|
|
# 根据有效数据的数量动态创建子图布局
|
|
|
num_valid_data = len(valid_data)
|
|
|
fig, axs = plt.subplots(
|
|
|
1, num_valid_data, figsize=(2 * num_valid_data, 4)
|
|
|
) # 动态调整布局
|
|
|
|
|
|
# 如果只有一个子图,axs 是一个单个的 Axes 对象而不是数组,需要将其转换为列表
|
|
|
if num_valid_data == 1:
|
|
|
axs = [axs]
|
|
|
|
|
|
# 绘制每个子图
|
|
|
for i, (title, values) in enumerate(valid_data.items()):
|
|
|
ax = axs[i] # 获取当前子图
|
|
|
y = list(values.values())
|
|
|
# 将蓝色柱子改为暗蓝色
|
|
|
bars = ax.bar(x, y, color=["#1E3A8A", "#FF8C00"], width=0.6)
|
|
|
|
|
|
# 设置子图标题和坐标轴标签
|
|
|
ax.set_title(
|
|
|
title, fontsize=12, fontweight="bold", color="#00008B"
|
|
|
) # 设置标题字体加粗深蓝色
|
|
|
|
|
|
# 设置坐标轴标签字体加粗深蓝色
|
|
|
ax.set_xticks(x)
|
|
|
ax.set_xticklabels(categories, fontsize=10, fontweight="bold", color="#00008B")
|
|
|
|
|
|
# 动态设置纵坐标范围
|
|
|
max_y = max(y) * 1.2 # 增加20%的范围
|
|
|
ax.set_ylim(0, max_y)
|
|
|
# 隐藏纵轴刻度线
|
|
|
ax.tick_params(axis="y", length=0)
|
|
|
ax.tick_params(axis="x", length=0)
|
|
|
|
|
|
# 添加自定义的淡颜色细长分割线
|
|
|
for y_tick in ax.get_yticks():
|
|
|
ax.axhline(y=y_tick, color="#87CEEB", linestyle="--", alpha=0.3)
|
|
|
|
|
|
# 设置刻度标签字体加粗深蓝色
|
|
|
ax.tick_params(axis="y", labelsize=12, labelcolor="#00008B")
|
|
|
|
|
|
# 添加数据标签
|
|
|
for bar in bars:
|
|
|
height = bar.get_height()
|
|
|
# 根据柱子颜色设置数据标签颜色
|
|
|
if bar == bars[0]:
|
|
|
color = "#1E3A8A" # 暗蓝色
|
|
|
else:
|
|
|
color = "#FF8C00" # 暗橙色
|
|
|
|
|
|
ax.text(
|
|
|
bar.get_x() + bar.get_width() / 2,
|
|
|
height,
|
|
|
f"{height}",
|
|
|
ha="center",
|
|
|
va="bottom",
|
|
|
fontsize=10,
|
|
|
fontweight="bold",
|
|
|
color=color,
|
|
|
)
|
|
|
|
|
|
# 添加变化百分比和箭头
|
|
|
change_percent = calculate_change_percentage(y[0], y[1])
|
|
|
# 根据变化百分比设置符号和颜色
|
|
|
if change_percent < 0:
|
|
|
symbol = "\u25bc" # 倒三角
|
|
|
color = "#006400" # 深绿色
|
|
|
# 调整箭头起始点和终点位置:从柱子的边角开始指向边角
|
|
|
bar0_height = bars[0].get_height()
|
|
|
bar1_height = bars[1].get_height()
|
|
|
ax.annotate(
|
|
|
"",
|
|
|
xy=(x[1] - bars[1].get_width() / 2+0.1, bar1_height),
|
|
|
#xy=(x[1], bar1_height),
|
|
|
#xytext=((x[0] + bars[0].get_width() / 2) + 0.05, bar0_height * 0.95),
|
|
|
xytext=((x[0] + bars[0].get_width() / 2), bar0_height),
|
|
|
arrowprops=dict(
|
|
|
arrowstyle="-|>",
|
|
|
mutation_scale=20, # 箭头大小
|
|
|
connectionstyle="arc3,rad=-0.4", # 调整为负值,箭头凸起
|
|
|
color="#FFD580",
|
|
|
linewidth=3,
|
|
|
capstyle='round',
|
|
|
joinstyle='round'
|
|
|
),
|
|
|
) # 浅橙色箭头,加粗
|
|
|
# 在子图中间显示变化百分比
|
|
|
ax.text(
|
|
|
0.5,
|
|
|
0.9,
|
|
|
f"{symbol}{abs(change_percent):.2f}%",
|
|
|
ha="center",
|
|
|
va="center",
|
|
|
transform=ax.transAxes,
|
|
|
fontsize=12,
|
|
|
fontweight="bold",
|
|
|
color=color,
|
|
|
)
|
|
|
elif change_percent > 0:
|
|
|
symbol = "\u25b2" # 正三角
|
|
|
color = "#FF0000" # 红色
|
|
|
# 调整箭头起始点和终点位置:从柱子的边角开始指向边角
|
|
|
bar0_height = bars[0].get_height()
|
|
|
bar1_height = bars[1].get_height()
|
|
|
ax.annotate(
|
|
|
"",
|
|
|
#xy=(x[1] - bars[1].get_width() / 2, bar1_height),
|
|
|
xy=(x[1] - bars[1].get_width() / 2, bar1_height),
|
|
|
#xytext=((x[0] + bars[0].get_width() / 2) + 0.05, bar0_height),
|
|
|
xytext=((x[0] + bars[0].get_width() / 2), bar0_height),
|
|
|
arrowprops=dict(
|
|
|
arrowstyle="-|>",
|
|
|
mutation_scale=20, # 箭头大小
|
|
|
connectionstyle="arc3,rad=0.4", # 调整为负值,箭头凸起
|
|
|
color="#FFD580",
|
|
|
linewidth=3,
|
|
|
),
|
|
|
) # 浅橙色箭头,加粗
|
|
|
# 在子图中间显示变化百分比
|
|
|
ax.text(
|
|
|
0.5,
|
|
|
0.9,
|
|
|
f"{symbol}{abs(change_percent):.2f}%",
|
|
|
ha="center",
|
|
|
va="center",
|
|
|
transform=ax.transAxes,
|
|
|
fontsize=12,
|
|
|
fontweight="bold",
|
|
|
color=color,
|
|
|
)
|
|
|
else:
|
|
|
symbol = ""
|
|
|
color = "#FFA500" # 橙色
|
|
|
# 调整箭头起始点和终点位置:从柱子的边角开始指向边角
|
|
|
bar0_height = bars[0].get_height()
|
|
|
bar1_height = bars[1].get_height()
|
|
|
ax.annotate(
|
|
|
"",
|
|
|
xy=(x[1] - bars[1].get_width() / 2+0.1, bar1_height),
|
|
|
xytext=((x[0] + bars[0].get_width() / 2), bar0_height),
|
|
|
arrowprops=dict(
|
|
|
arrowstyle="-|>",
|
|
|
mutation_scale=20, # 箭头大小
|
|
|
connectionstyle="arc3,rad=0", # 调整为负值,箭头凸起
|
|
|
color="#FFD580",
|
|
|
linewidth=3,
|
|
|
),
|
|
|
) # 浅橙色箭头,加粗
|
|
|
# 在子图中间显示变化百分比
|
|
|
ax.text(
|
|
|
0.5,
|
|
|
0.9,
|
|
|
f"持平",
|
|
|
ha="center",
|
|
|
va="center",
|
|
|
transform=ax.transAxes,
|
|
|
fontsize=12,
|
|
|
fontweight="bold",
|
|
|
color=color,
|
|
|
)
|
|
|
|
|
|
# 调整子图间距
|
|
|
plt.subplots_adjust(wspace=0) # 进一步减小子图之间的水平间距
|
|
|
plt.tight_layout(rect=[0, 0, 1, 0.95]) # 调整整体布局
|
|
|
|
|
|
# 获取当前脚本的绝对路径
|
|
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
|
project_root = os.path.dirname(os.path.dirname(current_dir))
|
|
|
|
|
|
# 创建 temp_picture 目录
|
|
|
temp_picture_dir = os.path.join(project_root, "temp_picture")
|
|
|
if not os.path.exists(temp_picture_dir):
|
|
|
os.makedirs(temp_picture_dir)
|
|
|
|
|
|
# 按年月创建子目录
|
|
|
month_dir = os.path.join(temp_picture_dir, f"{year}{month:02d}")
|
|
|
if not os.path.exists(month_dir):
|
|
|
os.makedirs(month_dir)
|
|
|
|
|
|
# 保存图形到指定目录
|
|
|
file_name = f"电力供应数据变化对比{year}{month:02d}{day:02d}.png"
|
|
|
file_path = os.path.join(month_dir, file_name)
|
|
|
plt.savefig(file_path, dpi=1200, bbox_inches="tight")
|
|
|
|
|
|
return file_path
|
|
|
# # 显示图形
|
|
|
# plt.show()
|
|
|
|
|
|
|
|
|
# plot_electricity_comparison(data)
|