init commit
This commit is contained in:
+29
@@ -0,0 +1,29 @@
|
|||||||
|
# Generated files
|
||||||
|
*.svg
|
||||||
|
*.pdf
|
||||||
|
*.tiff
|
||||||
|
*.png
|
||||||
|
*.jpg
|
||||||
|
*.esp
|
||||||
|
!images/*
|
||||||
|
|
||||||
|
# System generated files
|
||||||
|
# -- macOS
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
._*
|
||||||
|
|
||||||
|
# -- Windows
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# -- Linux
|
||||||
|
*~
|
||||||
|
|
||||||
|
# IDEs and editors' files
|
||||||
|
*.idea
|
||||||
|
*.vscode
|
||||||
|
*.sublime-workspace
|
||||||
|
*.sublime-project
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
# 论文部分格式要求
|
||||||
|
|
||||||
|
## 公式
|
||||||
|
|
||||||
|
1. 所有公式统一使用 `align` 块进行排版
|
||||||
|
|
||||||
|
```latex
|
||||||
|
\begin{align}
|
||||||
|
\label{refernce_label}
|
||||||
|
%
|
||||||
|
% ... ...
|
||||||
|
%
|
||||||
|
\end{align}
|
||||||
|
```
|
||||||
|
|
||||||
|
示例:
|
||||||
|
|
||||||
|
```latex
|
||||||
|
\begin{align}
|
||||||
|
\label{shannon–hartley_theorem}
|
||||||
|
C = \log \left( \det \left( \mathbf{I} + \frac{P}{N_0} \mathbf{H} \mathbf{H}^H \right) \right).
|
||||||
|
\end{align}
|
||||||
|
```
|
||||||
|
|
||||||
|
>$$
|
||||||
|
>\begin{align}
|
||||||
|
>C = \log \left( \det \left( \mathbf{I} + \frac{P}{N_0} \mathbf{H} \mathbf{H}^H \right) \right).
|
||||||
|
>\end{align}
|
||||||
|
>$$
|
||||||
|
|
||||||
|
2. 公式结尾必须有合适的标点,段落中的公式以 “`,`” 结尾,段落间的公式以 “`.`” 结尾
|
||||||
|
|
||||||
|
示例:
|
||||||
|
|
||||||
|
```latex
|
||||||
|
The capacity $C$ of a MIMO channel of a MIMO channel is given by,
|
||||||
|
%
|
||||||
|
\begin{align}
|
||||||
|
C = \log_2 \left( \det \left( \mathbf{I} + \mathbf{Q} \right) \right),
|
||||||
|
\end{align}
|
||||||
|
%
|
||||||
|
where the matrix $\mathbf{Q}$ is defined as follow.
|
||||||
|
%
|
||||||
|
\begin{align}
|
||||||
|
\mathbf{Q} = \frac{P}{N_0} \mathbf{H} \mathbf{H}^H.
|
||||||
|
\end{align}
|
||||||
|
```
|
||||||
|
|
||||||
|
>The capacity $C$ of a MIMO channel is given by,
|
||||||
|
>$$
|
||||||
|
>\begin{aligned}
|
||||||
|
>C = \log_2 \left( \det \left( \mathbf{I} + \mathbf{Q} \right) \right),
|
||||||
|
>\end{aligned}
|
||||||
|
>$$
|
||||||
|
>where the matrix $\mathbf{Q}$ is defined as follow.
|
||||||
|
>$$
|
||||||
|
>\begin{aligned}
|
||||||
|
>\mathbf{Q} = \frac{P}{N_0} \mathbf{H} \mathbf{H}^H.
|
||||||
|
>\end{aligned}
|
||||||
|
>$$
|
||||||
|
|
||||||
|
## 插图要求
|
||||||
|
|
||||||
|
1. 插图力求观感清晰,表意明确且全文格式统一。图片的基本格式要求如下:
|
||||||
|
|
||||||
|
* 比例 16:9 或 4:3
|
||||||
|
* 文字字号 12 pt
|
||||||
|
* 图例(Legend)字号:12 pt
|
||||||
|
* 坐标标签字号:12 pt
|
||||||
|
* 坐标刻度字号:10 pt
|
||||||
|
* 线条宽度:1 pt
|
||||||
|
* 标记大小:8 pt
|
||||||
|
* 图例、标签仅第一个单词首字母大写,其余小写;
|
||||||
|
* **字体与正文一致**,文本一般为衬线字体 `Times New Roman` 公式一般为 `Latin Modern Math`
|
||||||
|
|
||||||
|
> **注**:上述配置绘制图片大小为实际文章中一栏的物理尺寸,在显示器上会显得较小,建议最后输出图片时再使用;在正文中插入图片时需设置宽度为 `0.5 \textwidth` ,例如:
|
||||||
|
>
|
||||||
|
> ```latex
|
||||||
|
> \begin{figure}[!t]
|
||||||
|
> \centering
|
||||||
|
> \includegraphics[width=0.5\textwidth]{figures/fig1}
|
||||||
|
> \caption{Demo figure}
|
||||||
|
> % ... ...
|
||||||
|
> \end{figure}
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> **注**:MATLAB 只能使用内置的 Latex 解释器,无法渲染 `amsmath,amsfonts` 包中的特殊公式和符号。
|
||||||
|
|
||||||
|
2. 仿真插图要求:
|
||||||
|
|
||||||
|
* 不建议只使用颜色区分曲线,建议在线形上作区分,不同的 marker 表示不同的方法,同一个方法下的不同参数配置使用不同的 line;
|
||||||
|
* 图例要求简洁清晰,统一方法的不同参数配置可在图中使用箭头等方法标注趋势;
|
||||||
|
* 曲线点数不宜过多。
|
||||||
|
|
||||||
|
示例:
|
||||||
|
|
||||||
|
* Python matplotlib 绘制
|
||||||
|
|
||||||
|
")
|
||||||
|
|
||||||
|
* MATLAB 绘制
|
||||||
|
|
||||||
|
")
|
||||||
|
|
||||||
|
> **注**:matplotlib 与 MATLAB 的部分样式不同,渲染工具也不同,最终生成的文件略有区别。即便是同一套工具生成不同格式的图片文件(`pdf`,`eps`,`svg` 等)时也会存在一定误差,特别是字体渲染上的误差,导出为 `pdf` 时最能还原预览界面效果,具体可根据渲染效果进一步进行微调。
|
||||||
|
|
||||||
|
## 引用要求
|
||||||
|
|
||||||
|
1. 问内的公式、插图、表格可以添加并使用以下三个命令进行引用。
|
||||||
|
|
||||||
|
```latex
|
||||||
|
\let\eqlabel\eqref
|
||||||
|
\renewcommand{\eqref}[1]{Eq. \eqlabel{#1}}
|
||||||
|
\newcommand{\figref}[1]{Fig. \ref{#1}}
|
||||||
|
\newcommand{\tabref}[1]{Table. \ref{#1}}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 参考文献中期刊名字需要按照投稿要求进行缩写,IEEE 期刊标准缩写定义在 `IEEEabrv.bib` 中。
|
||||||
|
|
||||||
|
3. 所有参考文献标题**仅第一个单词首字母大写**。
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 43 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
@@ -0,0 +1,73 @@
|
|||||||
|
function hAnnot = arrow(startPoint, endPoint, ax, arrowType, varargin)
|
||||||
|
% ARROW Draws an annotation of specified type between two data points.
|
||||||
|
%
|
||||||
|
% hAnnot = ARROW(startPoint, endPoint, ax, arrowType) creates an
|
||||||
|
% annotation from the coordinate specified by startPoint to the coordinate
|
||||||
|
% specified by endPoint. The annotation type can be 'arrow', 'doublearrow',
|
||||||
|
% 'textarrow', etc.
|
||||||
|
%
|
||||||
|
% hAnnot = ARROW(startPoint, endPoint, ax, arrowType, Name, Value) allows
|
||||||
|
% additional customization of the annotation properties (e.g., color,
|
||||||
|
% arrowhead size, line width, etc.).
|
||||||
|
%
|
||||||
|
% INPUT:
|
||||||
|
% startPoint - 1x2 array, [x1, y1], coordinates of the start point
|
||||||
|
% in the data space of the current axes.
|
||||||
|
% endPoint - 1x2 array, [x2, y2], coordinates of the end point
|
||||||
|
% in the data space of the current axes.
|
||||||
|
% ax - (optional) Axes handle. If omitted, the current axes
|
||||||
|
% (gca) will be used.
|
||||||
|
% arrowType - (optional) Type of annotation ('arrow', 'doublearrow',
|
||||||
|
% 'textarrow', etc.). Default is 'arrow'.
|
||||||
|
% Name, Value - (optional) Name-value pairs to customize the annotation's
|
||||||
|
% appearance (e.g., 'Color', 'LineWidth', etc.).
|
||||||
|
%
|
||||||
|
% OUTPUT:
|
||||||
|
% hAnnot - Handle to the created annotation object.
|
||||||
|
%
|
||||||
|
% Example:
|
||||||
|
% figure;
|
||||||
|
% x = linspace(0, 10, 100);
|
||||||
|
% y = sin(x);
|
||||||
|
% plot(x, y);
|
||||||
|
% arrow([2, sin(2)], [8, sin(8)], gca, 'textarrow', 'Color', 'r', 'String', 'Text');
|
||||||
|
%
|
||||||
|
% Notes:
|
||||||
|
% The function automatically converts the data coordinates to normalized
|
||||||
|
% figure coordinates for annotation purposes.
|
||||||
|
|
||||||
|
% Input validation
|
||||||
|
if nargin < 2
|
||||||
|
error('arrow:InsufficientInputs', 'Both startPoint and endPoint must be specified.');
|
||||||
|
end
|
||||||
|
if nargin < 3 || isempty(ax)
|
||||||
|
ax = gca; % If axes handle is not provided, use the current axes
|
||||||
|
end
|
||||||
|
if nargin < 4 || isempty(arrowType)
|
||||||
|
arrowType = 'arrow'; % Default arrow type is 'arrow'
|
||||||
|
end
|
||||||
|
if numel(startPoint) ~= 2 || numel(endPoint) ~= 2
|
||||||
|
error('arrow:InvalidInput', 'startPoint and endPoint must be 1x2 arrays representing [x, y] coordinates.');
|
||||||
|
end
|
||||||
|
|
||||||
|
% Get the current axes position in normalized figure units
|
||||||
|
ax_pos = ax.Position;
|
||||||
|
|
||||||
|
% Convert data coordinates to normalized figure coordinates
|
||||||
|
startNorm = [(startPoint(1) - ax.XLim(1)) / diff(ax.XLim), ...
|
||||||
|
(startPoint(2) - ax.YLim(1)) / diff(ax.YLim)];
|
||||||
|
endNorm = [(endPoint(1) - ax.XLim(1)) / diff(ax.XLim), ...
|
||||||
|
(endPoint(2) - ax.YLim(1)) / diff(ax.YLim)];
|
||||||
|
|
||||||
|
% Map normalized data coordinates to figure normalized coordinates
|
||||||
|
startAnnot = [ax_pos(1) + startNorm(1) * ax_pos(3), ...
|
||||||
|
ax_pos(2) + startNorm(2) * ax_pos(4)];
|
||||||
|
endAnnot = [ax_pos(1) + endNorm(1) * ax_pos(3), ...
|
||||||
|
ax_pos(2) + endNorm(2) * ax_pos(4)];
|
||||||
|
|
||||||
|
% Create the specified type of annotation
|
||||||
|
hAnnot = annotation(arrowType, [startAnnot(1) endAnnot(1)], ...
|
||||||
|
[startAnnot(2) endAnnot(2)], ...
|
||||||
|
varargin{:}); % Pass additional name-value pairs
|
||||||
|
|
||||||
|
end
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
clear; clc; close all;
|
||||||
|
|
||||||
|
fig_config();
|
||||||
|
|
||||||
|
%% Initiate test plot data
|
||||||
|
x = linspace(0, 10, 14);
|
||||||
|
|
||||||
|
% -- bounds
|
||||||
|
upper_bound = ones(size(x)) * 4.5;
|
||||||
|
lower_bound = upper_bound * 0.4
|
||||||
|
|
||||||
|
% -- lines
|
||||||
|
method_1_1 = upper_bound - (upper_bound - lower_bound) .* exp(-0.7 * x);
|
||||||
|
method_1_2 = upper_bound - (upper_bound - lower_bound) .* exp(-0.5 * x);
|
||||||
|
method_1_3 = upper_bound - (upper_bound - lower_bound) .* exp(-0.3 * x);
|
||||||
|
method_2 = upper_bound - (upper_bound - lower_bound) .* exp(-0.5 * x) .* cos(x);
|
||||||
|
|
||||||
|
|
||||||
|
%% Plot
|
||||||
|
x_min = 0; x_max = 10;
|
||||||
|
y_min = 2; y_max = 6;
|
||||||
|
fig = figure(); hold on; box on; grid on;
|
||||||
|
line_optimal = plot(x, upper_bound, 'k-', 'DisplayName', 'Optimal');
|
||||||
|
line_method_1 = plot(x, method_1_1, '^b-', 'DisplayName', 'Method 1');
|
||||||
|
plot(x, method_1_2, '^b--')
|
||||||
|
plot(x, method_1_3, '^b-.')
|
||||||
|
line_method_2 = plot(x, method_2, '*r-', 'DisplayName', 'Method 2');
|
||||||
|
xlim([x_min, x_max]);
|
||||||
|
ylim([y_min, y_max]);
|
||||||
|
xticks(x_min:1:x_max);
|
||||||
|
yticks(y_min:1:y_max);
|
||||||
|
|
||||||
|
% -- Add arrow
|
||||||
|
arrow([2.5, 4.2], [3.8, 3]);
|
||||||
|
text(4, 3, '$\gamma = 1, 2, 3$')
|
||||||
|
|
||||||
|
% -- Add legends and labels
|
||||||
|
% h = findobj(fig, '-regexp', 'DisplayName', '.+');
|
||||||
|
lgd = legend([line_optimal, line_method_1, line_method_2]);
|
||||||
|
set(lgd, 'ItemTokenSize', [10, 5]);
|
||||||
|
ylabel("$\mathbf{E}\left[S\right]$")
|
||||||
|
xlabel("Rounds of Iteration")
|
||||||
|
|
||||||
|
% -- export
|
||||||
|
fig_export('example_matlab.pdf', 'pdf', '../../images')
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
function fig_config(customConfig)
|
||||||
|
% setFigureDefaults Sets default properties for all figures
|
||||||
|
%
|
||||||
|
% Usage:
|
||||||
|
% fig_config() % Applies default settings
|
||||||
|
% fig_config(userConfig) % Overrides defaults with userConfig
|
||||||
|
|
||||||
|
%% Define default settings
|
||||||
|
% In IEEETran, \textwidth is 7.1413 inches
|
||||||
|
% - Use `\printinunitsof{in}\prntlen{\textwidth}`
|
||||||
|
% - To output the \textwidth value in the generated document,
|
||||||
|
% you need to use the `printlen` and `layouts` packages.
|
||||||
|
textwidth_inches = 7.1413;
|
||||||
|
|
||||||
|
% Set the figure width to 0.5 times \textwidth and define the aspect ratio (16:9 or 4:3)
|
||||||
|
aspect = 16/9; % Aspect ratio (can also use 4/3)
|
||||||
|
axes_width = 0.75;
|
||||||
|
axes_hight = 0.75;
|
||||||
|
axes_pos = [0.15, 0.15, axes_width, axes_hight];
|
||||||
|
fig_width = 0.5 * textwidth_inches;
|
||||||
|
fig_hight = (fig_width * axes_width / aspect) / axes_hight;
|
||||||
|
|
||||||
|
defaultConfig = struct( ...
|
||||||
|
'defaultFigureUnits', 'inches', ...
|
||||||
|
'defaultFigurePosition', [0, 0, fig_width, fig_hight], ...
|
||||||
|
'defaultAxesPosition', axes_pos, ...
|
||||||
|
'defaultFigurePaperPositionMode', 'manual', ...
|
||||||
|
'defaultFigurePaperUnits', 'inches', ...
|
||||||
|
'defaultFigurePaperPosition', [0, 0, fig_width, fig_hight], ...
|
||||||
|
'defaultFigurePaperSize', [fig_width, fig_hight], ...
|
||||||
|
'defaultLineLineWidth', 0.5, ... % -- Line and marker
|
||||||
|
'defaultLineMarkerSize', 3, ...
|
||||||
|
'defaultAxesFontName', 'Times New Roman', ... % -- Fonts
|
||||||
|
'defaultTextFontName', 'Times New Roman', ...
|
||||||
|
'defaultLegendFontName', 'Times New Roman', ...
|
||||||
|
'defaultAxesLabelFontSizeMultiplier', 1.15, ...
|
||||||
|
'defaultAxesFontSize', 7, ...
|
||||||
|
'defaultTextFontSize', 10, ...
|
||||||
|
'defaultLegendFontSize', 7, ...
|
||||||
|
'defaultTextInterpreter', 'latex', ... % -- Interpreter
|
||||||
|
'defaultAxesTickLabelInterpreter', 'latex', ...
|
||||||
|
'defaultLegendInterpreter', 'latex', ...
|
||||||
|
'defaultAxesGridColor', [0.15, 0.15, 0.15], ... % -- Grid
|
||||||
|
'defaultAxesGridAlpha', 0.25, ...
|
||||||
|
'defaultAxesGridLineStyle', ':', ...
|
||||||
|
'defaultAxesGridLineWidth', 0.5, ...
|
||||||
|
'defaultArrowshapeHeadWidth', 6, ... % -- Arrow
|
||||||
|
'defaultArrowshapeHeadLength', 6 ...
|
||||||
|
);
|
||||||
|
|
||||||
|
% Merge user config with defaults
|
||||||
|
if nargin == 1 && ~isempty(customConfig)
|
||||||
|
userFields = fieldnames(customConfig);
|
||||||
|
for i = 1:length(userFields)
|
||||||
|
defaultConfig.(userFields{i}) = customConfig.(userFields{i});
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
% Iterate and set properties
|
||||||
|
fields = fieldnames(defaultConfig);
|
||||||
|
for i = 1:length(fields)
|
||||||
|
try
|
||||||
|
set(groot, fields{i}, defaultConfig.(fields{i}));
|
||||||
|
catch ME
|
||||||
|
errorStruct.message = sprintf("%s\nUse get(groot, 'factory') " + ...
|
||||||
|
"to get all the available parameters.", ME.message);
|
||||||
|
errorStruct.identifier = ME.identifier;
|
||||||
|
errorStruct.stack = ME.stack;
|
||||||
|
error(errorStruct)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
function fig_export(filename, format, folder, dpi, fig)
|
||||||
|
% EXPORT_CHART Save the current MATLAB figure or a specified figure in the selected image format.
|
||||||
|
%
|
||||||
|
% Parameters:
|
||||||
|
% - filename (string, optional): The output file name. If it has no extension, one will be
|
||||||
|
% added based on the format. If missing or empty, a default
|
||||||
|
% name 'exported_plot' is used.
|
||||||
|
% - format (string): The desired file format for the export. Default is 'pdf'.
|
||||||
|
% Accepted formats are 'png', 'jpg', 'tiff', 'svg', 'pdf', 'esp'.
|
||||||
|
% - folder (string): The directory where the image file will be saved. Default is the current directory.
|
||||||
|
% - dpi (int): Resolution in dots per inch. Default is 96.
|
||||||
|
% - fig (figure handle, optional): The MATLAB Figure object to export. If empty, the current active figure is used.
|
||||||
|
%
|
||||||
|
% Notes:
|
||||||
|
% - The function creates the folder if it doesn't exist.
|
||||||
|
% - Ensures compatibility with supported MATLAB formats.
|
||||||
|
|
||||||
|
if nargin < 1 || isempty(filename)
|
||||||
|
timestamp = char(datetime('now', 'Format','yyyyMMdd_HHmmSS'));
|
||||||
|
filename = ['exported_plot_' timestamp];
|
||||||
|
end
|
||||||
|
if nargin < 2 || isempty(format)
|
||||||
|
format = 'pdf';
|
||||||
|
end
|
||||||
|
if nargin < 3 || isempty(folder)
|
||||||
|
folder = '.';
|
||||||
|
end
|
||||||
|
if nargin < 4 || isempty(dpi)
|
||||||
|
dpi = 96;
|
||||||
|
end
|
||||||
|
if nargin < 5 || isempty(fig)
|
||||||
|
fig = gcf;
|
||||||
|
end
|
||||||
|
|
||||||
|
% Add extension if missing
|
||||||
|
[~, ~, ext] = fileparts(filename);
|
||||||
|
if isempty(ext)
|
||||||
|
filename = [filename '.' format];
|
||||||
|
else
|
||||||
|
format = ext(2:end); % Use extension for format
|
||||||
|
end
|
||||||
|
|
||||||
|
% Validate folder and create if necessary
|
||||||
|
if ~exist(folder, 'dir')
|
||||||
|
mkdir(folder);
|
||||||
|
end
|
||||||
|
|
||||||
|
% Construct full file path
|
||||||
|
filepath = fullfile(folder, filename);
|
||||||
|
|
||||||
|
% Format to '-d' option mapping
|
||||||
|
supportedFormats = struct( ...
|
||||||
|
'png', '-dpng', ...
|
||||||
|
'jpg', '-djpeg', ...
|
||||||
|
'tiff', '-dtiff', ...
|
||||||
|
'svg', '-dsvg', ...
|
||||||
|
'pdf', '-dpdf', ...
|
||||||
|
'eps', '-depsc' ...
|
||||||
|
);
|
||||||
|
if ~isfield(supportedFormats, lower(format))
|
||||||
|
error('Unsupported format "%s". Supported formats are: %s.', ...
|
||||||
|
format, strjoin(fieldnames(supportedFormats), ', '));
|
||||||
|
end
|
||||||
|
|
||||||
|
% Get the corresponding '-d' option
|
||||||
|
dOption = supportedFormats.(lower(format));
|
||||||
|
|
||||||
|
% Attempt to save the figure
|
||||||
|
try
|
||||||
|
% Include resolution for raster formats
|
||||||
|
if ismember(lower(format), {'png', 'jpg', 'tiff'})
|
||||||
|
print(fig, filepath, dOption, ['-r' num2str(dpi)]);
|
||||||
|
else
|
||||||
|
print(fig, filepath, dOption);
|
||||||
|
end
|
||||||
|
fprintf('Exported image to: "%s" as %s\n', filepath, format);
|
||||||
|
catch ME
|
||||||
|
fprintf('Failed to export the figure: %s\n', ME.message);
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
from plt_util import plt_config, plt_export
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from matplotlib.patches import FancyArrowPatch
|
||||||
|
import matplotlib.ticker as ticker
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
plt_config(plt)
|
||||||
|
|
||||||
|
## Initiate test plot data
|
||||||
|
x = np.linspace(0, 10, 14)
|
||||||
|
|
||||||
|
# -- bounds
|
||||||
|
upper_bound = np.ones_like(x) * 4.5
|
||||||
|
lower_bound = upper_bound * 0.4
|
||||||
|
|
||||||
|
# -- lines
|
||||||
|
method_1_1 = upper_bound - (upper_bound - lower_bound) * np.exp(-0.7 * x)
|
||||||
|
method_1_2 = upper_bound - (upper_bound - lower_bound) * np.exp(-0.5 * x)
|
||||||
|
method_1_3 = upper_bound - (upper_bound - lower_bound) * np.exp(-0.3 * x)
|
||||||
|
method_2 = upper_bound - (upper_bound - lower_bound) * np.exp(-0.5 * x) * np.cos(x)
|
||||||
|
|
||||||
|
|
||||||
|
## Plot
|
||||||
|
x_min, x_max = 0, 10
|
||||||
|
y_min, y_max = 2, 6
|
||||||
|
plt.plot(x, upper_bound, 'k-', label='Optimal')
|
||||||
|
plt.plot(x, method_1_1, '^b-', label='Method 1')
|
||||||
|
plt.plot(x, method_1_2, '^b--')
|
||||||
|
plt.plot(x, method_1_3, '^b-.')
|
||||||
|
plt.plot(x, method_2, '*r-', label='Method 2')
|
||||||
|
plt.xlim(x_min, x_max)
|
||||||
|
plt.ylim(y_min, y_max)
|
||||||
|
plt.grid(True, linestyle='--', color='gray', linewidth=0.5)
|
||||||
|
|
||||||
|
# -- Add arrow
|
||||||
|
arrow = FancyArrowPatch((2.5, 4.2), # start point
|
||||||
|
(3.8, 3), # end point
|
||||||
|
arrowstyle='-|>', # arrow style
|
||||||
|
mutation_scale=10, # arrow head size
|
||||||
|
color='black', # arrow color
|
||||||
|
linewidth=0.5) # line width
|
||||||
|
plt.gca().add_patch(arrow)
|
||||||
|
plt.text(4, 3, '$\gamma = 1, 2, 3$')
|
||||||
|
|
||||||
|
# -- Add legends and labels
|
||||||
|
plt.legend()
|
||||||
|
plt.gca().xaxis.set_major_locator(ticker.MultipleLocator(1))
|
||||||
|
plt.gca().yaxis.set_major_locator(ticker.MultipleLocator(1))
|
||||||
|
plt.ylabel(r"$\mathbb{E}\left[S\right]$")
|
||||||
|
plt.xlabel(r'Rounds of Iteration')
|
||||||
|
|
||||||
|
# -- export and show
|
||||||
|
plt_export(filename='example_python.pdf',
|
||||||
|
folder='../../images',
|
||||||
|
format='pdf')
|
||||||
|
plt.show()
|
||||||
@@ -0,0 +1,249 @@
|
|||||||
|
import os, re, platform
|
||||||
|
import matplotlib as mpl
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import pandas as pd
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
def plt_config(plt, custom_rcparams=None):
|
||||||
|
"""
|
||||||
|
Configure matplotlib runtime parameters for consistent styling in IEEETran-like figures.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
- plt: The matplotlib module to configure.
|
||||||
|
- custom_rcparams: (dict, optional) Custom runtime parameters to override or extend the defaults.
|
||||||
|
Default is None.
|
||||||
|
"""
|
||||||
|
# In IEEETran, \textwidth is 7.1413 inches
|
||||||
|
# - Use `\printinunitsof{in}\prntlen{\textwidth}`
|
||||||
|
# - To output the \textwidth value in the generated document,
|
||||||
|
# you need to use the `printlen` and `layouts` packages.
|
||||||
|
textwidth_inches = 7.1413
|
||||||
|
|
||||||
|
# Configure figure dimensions: width as 0.5 * \textwidth and aspect ratio (16:9 or 4:3)
|
||||||
|
aspect = 16 / 9 # Aspect ratio (can also use 4/3)
|
||||||
|
axes_left, axes_right, axes_bottom, axes_top = 0.15, 0.9, 0.15, 0.9
|
||||||
|
axes_width = axes_right - axes_left
|
||||||
|
axes_height = axes_top - axes_bottom
|
||||||
|
fig_width = 0.5 * textwidth_inches
|
||||||
|
fig_height = (fig_width * axes_width / aspect) / axes_height
|
||||||
|
|
||||||
|
# Default runtime parameters
|
||||||
|
# -- call plt.rcParams.keys() to list all available rcParameter
|
||||||
|
default_rcparams = {
|
||||||
|
"text.usetex": True, # Use LaTeX for rendering text
|
||||||
|
"text.latex.preamble": r'\usepackage{amsmath,amsfonts}', # Load LaTeX packages
|
||||||
|
"font.family": 'Times New Roman', # Set font family
|
||||||
|
"font.weight": 'normal', # Set font weight
|
||||||
|
"font.size": 10, # Set base font size
|
||||||
|
"figure.figsize": (fig_width, fig_height), # Set figure size
|
||||||
|
"lines.linewidth": 0.5, # Set line width
|
||||||
|
"lines.markeredgewidth": 0.5, # Set marker edge width
|
||||||
|
"lines.markersize": 2, # Set marker size
|
||||||
|
"figure.subplot.bottom": axes_bottom, # Subplot bottom margin
|
||||||
|
"figure.subplot.left": axes_left, # Subplot left margin
|
||||||
|
"figure.subplot.right": axes_right, # Subplot right margin
|
||||||
|
"figure.subplot.top": axes_top, # Subplot top margin
|
||||||
|
"legend.markerscale": 1.0, # Scale of markers in the legend
|
||||||
|
"legend.handleheight": 0.5, # Height of legend handles
|
||||||
|
"legend.handlelength": 1.5, # Length of legend handles
|
||||||
|
"legend.handletextpad": 0.25, # Padding between handle and text
|
||||||
|
"legend.columnspacing": 1.5, # Spacing between legend columns
|
||||||
|
"legend.labelspacing": 0.25, # Spacing between legend entries
|
||||||
|
"legend.fontsize": 7, # Legend font size
|
||||||
|
"legend.borderpad": 0.2, # Padding inside the legend box
|
||||||
|
"axes.labelsize": 8, # Axis label font size
|
||||||
|
"axes.linewidth": 0.5, # Axis line width
|
||||||
|
"axes.grid": True, # Enable grid
|
||||||
|
"axes.formatter.limits": (-3, 3),
|
||||||
|
"axes.formatter.useoffset": True,
|
||||||
|
"grid.color": '#0F0F0F', # Grid color
|
||||||
|
"grid.alpha": 0.25, # Grid transparency
|
||||||
|
"grid.linestyle": ':', # Grid line style
|
||||||
|
"grid.linewidth": 0.5, # Grid line width
|
||||||
|
"xtick.direction": "in", # Direction of x-ticks
|
||||||
|
"ytick.direction": "in", # Direction of y-ticks
|
||||||
|
"xtick.labelsize": 7, # Font size for x-tick labels
|
||||||
|
"ytick.labelsize": 7 # Font size for y-tick labels
|
||||||
|
}
|
||||||
|
|
||||||
|
# Override or extend the default parameters if custom settings are provided
|
||||||
|
if custom_rcparams is not None:
|
||||||
|
default_rcparams.update(custom_rcparams)
|
||||||
|
|
||||||
|
# Apply the final configuration to matplotlib
|
||||||
|
# -- use plt.rcParams.keys() to list all available parameters
|
||||||
|
plt.rcParams.update(default_rcparams)
|
||||||
|
|
||||||
|
def plt_export(filename=None, format='pdf', folder='.', dpi=96, fig=None):
|
||||||
|
"""
|
||||||
|
Save the current Matplotlib figure or a specified figure in the selected image format.
|
||||||
|
|
||||||
|
This function should be a standard part of chart scripts, enabling the "Export image"
|
||||||
|
functionality of the IDE and `opp_charttool` to work seamlessly.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
- filename (str, optional): The output file name. If it has no extension, one will be added based on the format.
|
||||||
|
If missing or empty, a sanitized version of the chart name is used.
|
||||||
|
- format (str): The desired file format for the export. Default is 'pdf'.
|
||||||
|
Accepted formats are those supported by Matplotlib (e.g., 'png', 'jpg', 'svg', 'pdf', etc.).
|
||||||
|
- folder (str): The directory where the image file will be saved. Default is the current directory.
|
||||||
|
- dpi (int): Dots per inch setting, default is 96. For raster image formats, the image dimensions are
|
||||||
|
produced as width (or height) times dpi.
|
||||||
|
- fig (matplotlib.figure.Figure, optional): The Matplotlib Figure object to export. If None, the current active figure is used.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- For export, even IDE-native charts are rendered using Matplotlib.
|
||||||
|
- `dpi` controls the resolution for raster image formats while maintaining the chart's aspect ratio and relative sizes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Validate the format
|
||||||
|
valid_formats = mpl.figure.Figure().savefig.__code__.co_varnames
|
||||||
|
if format.lower() not in mpl.figure.Figure().canvas.get_supported_filetypes().keys():
|
||||||
|
raise ValueError(f"Unsupported format '{format}'. Supported formats are: {', '.join(mpl.figure.Figure().canvas.get_supported_filetypes().keys())}")
|
||||||
|
|
||||||
|
# Handle filename
|
||||||
|
if not filename:
|
||||||
|
# If filename is None or empty, use a default name
|
||||||
|
filename = 'exported_plot'
|
||||||
|
|
||||||
|
if not re.match(r".+\.\w{3,4}$", filename):
|
||||||
|
filename += f".{format.lower()}"
|
||||||
|
|
||||||
|
filepath = os.path.normpath(os.path.join(folder, filename))
|
||||||
|
os.makedirs(os.path.dirname(filepath) or ".", exist_ok=True)
|
||||||
|
|
||||||
|
# Function to create metadata
|
||||||
|
def _make_image_metadata():
|
||||||
|
creator_info = (
|
||||||
|
f"Matplotlib {mpl.__version__}; "
|
||||||
|
f"Pandas {pd.__version__}; "
|
||||||
|
f"Python {platform.python_version()}; "
|
||||||
|
f"{platform.platform()}"
|
||||||
|
)
|
||||||
|
return {"Creator": creator_info}
|
||||||
|
|
||||||
|
# Select the figure to save
|
||||||
|
target_fig = fig or plt.gcf()
|
||||||
|
|
||||||
|
# Prepare metadata if supported
|
||||||
|
metadata = _make_image_metadata() if format.lower() in ['pdf', 'svg', 'eps'] else None
|
||||||
|
|
||||||
|
# Attempt to save the figure
|
||||||
|
try:
|
||||||
|
target_fig.savefig(filepath, format=format, dpi=dpi, metadata=metadata, bbox_inches='tight')
|
||||||
|
print(f'Exported image to: "{filepath}" as {format}')
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Failed to save with metadata due to: {e}. Retrying without metadata.")
|
||||||
|
try:
|
||||||
|
target_fig.savefig(filepath, format=format, dpi=dpi, bbox_inches='tight')
|
||||||
|
print(f'Exported image to: "{filepath}" as {format} without metadata')
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Failed to save the figure: {e}")
|
||||||
|
|
||||||
|
def plt_export(filename=None, format='pdf', folder='.', dpi=96, fig=None):
|
||||||
|
"""
|
||||||
|
Save the current Matplotlib figure or a specified figure in the selected image format.
|
||||||
|
|
||||||
|
This function should be a standard part of chart scripts, enabling the "Export image"
|
||||||
|
functionality of the IDE and `opp_charttool` to work seamlessly.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
- filename (str, optional): The output file name. If it has no extension, one will be
|
||||||
|
added based on the format. If missing or empty, a default
|
||||||
|
name 'exported_plot' is used.
|
||||||
|
- format (str): The desired file format for the export. Default is 'pdf'.
|
||||||
|
Accepted formats are those supported by Matplotlib (e.g., 'png', 'jpg',
|
||||||
|
'svg', 'pdf', etc.).
|
||||||
|
- folder (str): The directory where the image file will be saved. Default is the current directory.
|
||||||
|
- dpi (int): Dots per inch setting, default is 96. For raster image formats, the image
|
||||||
|
dimensions are produced as width (or height) times dpi.
|
||||||
|
- fig (matplotlib.figure.Figure, optional): The Matplotlib Figure object to export. If None,
|
||||||
|
the current active figure is used.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
- For export, even IDE-native charts are rendered using Matplotlib.
|
||||||
|
- `dpi` controls the resolution for raster image formats while maintaining the chart's
|
||||||
|
aspect ratio and relative sizes.
|
||||||
|
"""
|
||||||
|
# Select the figure to save
|
||||||
|
target_fig = fig or plt.gcf()
|
||||||
|
|
||||||
|
# Validate the format
|
||||||
|
supported_formats = target_fig.canvas.get_supported_filetypes()
|
||||||
|
if format.lower() not in supported_formats:
|
||||||
|
raise ValueError(
|
||||||
|
f"Unsupported format '{format}'. Supported formats are: "
|
||||||
|
f"{', '.join(supported_formats.keys())}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Handle filename
|
||||||
|
if not filename:
|
||||||
|
# Generate a default filename with a timestamp
|
||||||
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||||
|
filename = f'exported_plot_{timestamp}'
|
||||||
|
|
||||||
|
if not re.match(r".+\.\w{3,4}$", filename):
|
||||||
|
filename += f".{format.lower()}"
|
||||||
|
|
||||||
|
filepath = os.path.normpath(os.path.join(folder, filename))
|
||||||
|
os.makedirs(os.path.dirname(filepath) or ".", exist_ok=True)
|
||||||
|
|
||||||
|
def _get_mpl_backend_for_image_format(format):
|
||||||
|
return {
|
||||||
|
"png": "AGG",
|
||||||
|
"jpg": "AGG",
|
||||||
|
"jpeg": "AGG",
|
||||||
|
"tif": "AGG",
|
||||||
|
"tiff": "AGG",
|
||||||
|
"raw": "AGG",
|
||||||
|
"svg": "SVG",
|
||||||
|
"svgz": "SVG",
|
||||||
|
"ps" : "PS",
|
||||||
|
"eps": "PS",
|
||||||
|
"pdf": "PDF",
|
||||||
|
"pgf": "PGF",
|
||||||
|
}.get(format.lower(), None)
|
||||||
|
|
||||||
|
# Function to create metadata
|
||||||
|
def _make_image_metadata():
|
||||||
|
creator_info = (
|
||||||
|
f"Matplotlib {mpl.__version__}; "
|
||||||
|
f"Pandas {pd.__version__}; "
|
||||||
|
f"Python {platform.python_version()}; "
|
||||||
|
f"{platform.platform()}"
|
||||||
|
)
|
||||||
|
return {"Creator": creator_info}
|
||||||
|
|
||||||
|
# Prepare metadata if supported
|
||||||
|
metadata = _make_image_metadata()
|
||||||
|
# Explicitly select a non-interactive backend appropriate for the export format,
|
||||||
|
# and keep auto-selection for any other formats not listed here.
|
||||||
|
backend = _get_mpl_backend_for_image_format(format)
|
||||||
|
|
||||||
|
# Attempt to save the figure
|
||||||
|
try:
|
||||||
|
target_fig.savefig(
|
||||||
|
filepath,
|
||||||
|
format=format,
|
||||||
|
dpi=dpi,
|
||||||
|
metadata=metadata,
|
||||||
|
backend=backend
|
||||||
|
)
|
||||||
|
print(f'Exported image to: "{filepath}" as {format}')
|
||||||
|
except Exception as e:
|
||||||
|
print(
|
||||||
|
f"Failed to save with metadata due to: {e}. "
|
||||||
|
"Retrying without metadata."
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
target_fig.savefig(
|
||||||
|
filepath,
|
||||||
|
format=format,
|
||||||
|
dpi=dpi,
|
||||||
|
backend=backend
|
||||||
|
)
|
||||||
|
print(
|
||||||
|
f'Exported image to: "{filepath}" as {format} without metadata'
|
||||||
|
)
|
||||||
|
except Exception as e_inner:
|
||||||
|
print(f"Failed to save the figure: {e_inner}")
|
||||||
Reference in New Issue
Block a user