我认为子图四有问题,请修改;%% ========== Enhanced Visualization ==========
fprintf('\n%s\n', repmat('-', 1, 70));
fprintf('Generating enhanced visualization plots...\n');
% Create figure with improved layout
fig = figure('Name', 'Unit Commitment Results', ...
'Position', [100, 100, 1200, 900], ...
'Color', 'white');
% 1. Unit Commitment Schedule - IMPROVED
subplot(3, 2, [1,2]);
hold on;
% Create custom colormap (green=on, red=off)
cmap = [1 0.7 0.7; 0.7 1 0.7];
% Plot commitment status
h = imagesc(commitment);
colormap(cmap);
set(gca, 'YTick', 1:numUnits, ...
'YTickLabel', arrayfun(@(x) sprintf('Unit %d', x), 1:numUnits, 'UniformOutput', false), ...
'XTick', 1:T, ...
'TickDir', 'out');
xlabel('Time (Hours)');
title('Unit Commitment Status', 'FontWeight', 'bold');
% Add status text
for i = 1:numUnits
for t = 1:T
if commitment(i,t) > 0.5
text(t, i, 'ON', 'HorizontalAlignment', 'center', 'Color', [0 0.5 0], 'FontWeight', 'bold');
else
text(t, i, 'OFF', 'HorizontalAlignment', 'center', 'Color', [0.6 0 0]);
end
end
end
grid on;
box on;
hold off;
% 2. Generation Stack vs Load
subplot(3, 2, 3);
hold on;
% 确保输入数据为双精度类型避免计算错误
power = double(power);
load_demand = double(load_demand);
% 创建自定义颜色映射(每个机组不同颜色)
unit_colors = parula(numUnits); % 使用感知均匀的色图
% 确保堆叠顺序从大到小(最稳定机组在底部)
[~, sort_idx] = sort(mean(power, 2), 'descend');
power_sorted = power(sort_idx, :);
% 堆叠图绘制(显式控制每层颜色)
h_area = area(1:T, power_sorted', ...
'EdgeColor', 'none', ...
'FaceAlpha', 0.8);
% 为每个区域设置特定颜色
for i = 1:numUnits
h_area(i).FaceColor = unit_colors(i, :);
end
% 负荷曲线绘制(增强可见性)
h_load = plot(1:T, load_demand, ...
'Color', [0.3 0.6 0.9], ... % 纯黑色
'LineWidth', 1, ... % 加粗线宽
'Marker', '*', ...
'MarkerSize', 6, ...
'MarkerFaceColor', 'w');
% 创建正确的标签(保持原始机组编号)
legend_labels = arrayfun(@(idx) sprintf('Unit 0%d', sort_idx(idx)), 1:numUnits, 'UniformOutput', false);
legend_labels = [legend_labels, {'Load e'}];
legend([h_area, h_load], legend_labels, ...
'Location', 'bestoutside', ... % 动态列数
'FontSize', 8); % 缩小字体避免重叠
title('Generation Stack & Load', 'FontWeight', 'bold');
xlabel('Time (Hours)', 'FontWeight', 'bold');
ylabel('Power (MW)', 'FontWeight', 'bold');
grid on;
box on;
xlim([0.5 T+0.5]);
% 3. Power Distribution - CORRECTED & ENHANCED
subplot(3, 2, 4);
hold on;
% Pre-calculate unit capacities
unit_capacities = [unit_params.Pmax] - [unit_params.Pmin]; % 所有机组的容量区间
% Calculate weighted hourly utilization
utilization = zeros(1, T);
num_online_units = sum(commitment, 1); % 每小时运行的机组数
for t = 1:T
total_capacity_weight = 0; % 总容量权重
weighted_util = 0; % 加权利用率
for i = 1:numUnits
if commitment(i,t)
% 计算当前机组的利用率百分比
unit_util = (power(i,t) - unit_params(i).Pmin) / ...
unit_capacities(i) * 100;
% 权重基于机组容量(容量越大权重越高)
weight = unit_capacities(i);
weighted_util = weighted_util + unit_util * weight;
total_capacity_weight = total_capacity_weight + weight;
end
end
% 处理无机组运行的情况
if total_capacity_weight > 0
utilization(t) = weighted_util / total_capacity_weight;
else
utilization(t) = 0; % 无机组运行时利用率为0
end
end
% Plot utilization with gradient color
colors = winter(T); % 使用winter色图创建时间渐变
for t = 1:T
bar(t, utilization(t), 'FaceColor', colors(t, :), 'BarWidth', 0.8);
end
% Plot average line with enhanced style
avg_util = mean(utilization(num_online_units > 0)); % 仅计算有机组运行的小时
h_avg = plot(xlim, [avg_util avg_util], 'r*--');
title('Weighted Unit Utilization (%)', 'FontWeight', 'bold');
xlabel('Time (Hours)', 'FontWeight', 'bold');
ylabel('Utilization %', 'FontWeight', 'bold');
legend(h_avg, sprintf('Average: %.1f%%', avg_util));
grid on;
box on;
xlim([0.5 T+0.5]);
ylim([0 110]);
%% 4. Spinning Reserve - IMPROVED
subplot(3, 2, 5);
hold on;
% Plot reserve
bar(1:T, reserves, 'FaceColor', [0.2 0.7 0.8], 'BarWidth', 0.7);
% Reserve requirement line
res_req = 0.03 * load_demand;
plot(1:T, res_req, 'r--', 'LineWidth', 1.5, 'Marker', 's', 'MarkerSize', 4, 'MarkerFaceColor', 'w');
% Add data labels
for t = 1:T
text(t, reserves(t)+5, sprintf('%.1f', reserves(t)), ...
'HorizontalAlignment', 'center', 'FontSize', 8);
end
title('Spinning Reserve', 'FontWeight', 'bold');
xlabel('Time (Hours)');
ylabel('Reserve (MW)');
legend('Actual Reserve', 'Requirement', 'Location', 'best');
grid on;
box on;
xlim([0.5 T+0.5]);
ylim([0 max(reserves)*1.3]);
%% 5. Operating Costs - CORRECTED
subplot(3, 2, 6);
hold on;
% Calculate hourly costs (FIXED variable name conflict)
hourly_cost = zeros(1, T);
for t = 1:T
for i = 1:numUnits
if commitment(i,t)
P_val = power(i,t); % Corrected variable name
cost = unit_params(i).a * P_val^2 + unit_params(i).b * P_val + unit_params(i).c;
hourly_cost(t) = hourly_cost(t) + cost;
end
end
end
% Plot costs with markers
plot(1:T, hourly_cost, 'o-', 'Color', [0.8 0.2 0.2], ...
'LineWidth', 1.5, 'MarkerSize', 6, 'MarkerFaceColor', [1 0.8 0.8]);
% Add cost labels
for t = 1:T
text(t, hourly_cost(t)+50, sprintf('$%.0f', hourly_cost(t)), ...
'HorizontalAlignment', 'center', 'FontSize', 8, 'Rotation', 90);
end
title('Operating Costs', 'FontWeight', 'bold');
xlabel('Time (Hours)');
ylabel('Cost ($)');
grid on;
box on;
xlim([0.5 T+0.5]);
ylim([0 max(hourly_cost)*1.3]);
%% Final adjustments
sgtitle('Enhanced Unit Commitment Analysis', 'FontSize', 16, 'FontWeight', 'bold');
set(findall(fig, 'Type', 'axes'), 'FontSize', 10, 'Box', 'on', 'GridAlpha', 0.3);
% Add report summary
report_str = {
sprintf('Total Cost: $%.2f', objective_value);
sprintf('Fuel Cost: $%.2f', total_fuel);
sprintf('Avg Reserve: %.1f MW', mean(reserves));
sprintf('Peak Load: %.1f MW', max(load_demand))
};
annotation('textbox', [0.75 0.15 0.2 0.1], 'String', report_str, ...
'BackgroundColor', [0.95 0.95 0.95], 'EdgeColor', 'k', ...
'FontSize', 10, 'FontWeight', 'bold');
% Save figure in high resolution
save_path = 'uc_enhanced_results.png';
print(fig, save_path, '-dpng', '-r300');
fprintf('>>> Enhanced visualization saved: %s\n', save_path);
最新发布