折腾笔记[54]-使用kimi进行科研绘图
摘要
在macOS上使用kimi-cli的plot-skill技能,通过D2和Python matplotlib创建科研/技术图表,采用统一的马卡龙配色方案和奶油色背景.
声明
本文人类为第一作者, 龙虾为通讯作者. 本文有AI生成内容.
plot-skill技能
SKILL.md
<hr>
<p>name: plot-skill</p>
<h2 id="description-scientific-and-technical-diagram-plotting-with-macaron-color-scheme-cream-background-and-chinese-text-support-use-when-the-user-needs-to-create-flowcharts-system-architecture-diagrams-control-system-diagrams-line-charts-bar-charts-or-other-research-academic-figures-supports-d2-for-structural-diagrams-and-python-matplotlib-for-data-charts-all-outputs-use-a-consistent-macaron-pastel-color-palette-with-cream-fff8e7-background-and-black-text-">description: Scientific and technical diagram plotting with macaron color scheme, cream background, and Chinese text support. Use when the user needs to create flowcharts, system architecture diagrams, control system diagrams, line charts, bar charts, or other research/academic figures. Supports D2 for structural diagrams and Python matplotlib for data charts. All outputs use a consistent macaron pastel color palette with cream (#FFF8E7) background and black text.</h2>
<h1 id="plot-skill-">Plot Skill - 科研绘图技能</h1>
<h2 id="overview">Overview</h2>
<p>This skill provides a unified workflow for creating scientific and technical diagrams with:</p>
<ul>
<li><strong>Macaron pastel color palette</strong> (soft blue, pink, green, yellow, purple, orange)</li>
<li><strong>Cream background</strong> (<code>#FFF8E7</code>) with <strong>black text</strong> (<code>#222222</code>)</li>
<li><strong>Chinese text support</strong> (no garbled characters)</li>
<li><strong>Straight lines with rounded corners</strong> for connections</li>
<li><strong>Consistent styling</strong> across all diagram types</li>
</ul>
<h2 id="color-palette">Color Palette</h2>
<table>
<thead>
<tr>
<th>Name</th>
<th>Fill</th>
<th>Stroke</th>
<th>Usage</th>
</tr>
</thead>
<tbody>
<tr>
<td>Blue</td>
<td><code>#A8D8EA</code></td>
<td><code>#7FBCD2</code></td>
<td>AI/model nodes, primary processes</td>
</tr>
<tr>
<td>Pink</td>
<td><code>#FFB7B2</code></td>
<td><code>#E8A0A0</code></td>
<td>Human nodes, corrections, errors</td>
</tr>
<tr>
<td>Green</td>
<td><code>#B5EAD7</code></td>
<td><code>#8FD4B8</code></td>
<td>Output, success, final results</td>
</tr>
<tr>
<td>Yellow</td>
<td><code>#FFDAC1</code></td>
<td><code>#E8C0A0</code></td>
<td>Sensors, warnings, intermediate</td>
</tr>
<tr>
<td>Purple</td>
<td><code>#C7CEEA</code></td>
<td><code>#A8B0D8</code></td>
<td>Secondary processes</td>
</tr>
<tr>
<td>Orange</td>
<td><code>#FFD8A8</code></td>
<td><code>#E8C090</code></td>
<td>Alternative paths</td>
</tr>
<tr>
<td>Container</td>
<td><code>#F5F0E8</code></td>
<td><code>#D8D0C0</code></td>
<td>Grouping containers</td>
</tr>
<tr>
<td>Background</td>
<td><code>#FFF8E7</code></td>
<td>-</td>
<td>Diagram background</td>
</tr>
<tr>
<td>Text</td>
<td><code>#222222</code></td>
<td>-</td>
<td>All text</td>
</tr>
</tbody>
</table>
<h2 id="tool-selection">Tool Selection</h2>
<table>
<thead>
<tr>
<th>Diagram Type</th>
<th>Tool</th>
<th>Output</th>
</tr>
</thead>
<tbody>
<tr>
<td>Flowchart</td>
<td>D2</td>
<td>PNG/SVG</td>
</tr>
<tr>
<td>System architecture</td>
<td>D2</td>
<td>PNG/SVG</td>
</tr>
<tr>
<td>Control system</td>
<td>D2</td>
<td>PNG/SVG</td>
</tr>
<tr>
<td>Line chart</td>
<td>Python matplotlib</td>
<td>PNG</td>
</tr>
<tr>
<td>Bar chart</td>
<td>Python matplotlib</td>
<td>PNG</td>
</tr>
<tr>
<td>Scatter plot</td>
<td>Python matplotlib</td>
<td>PNG</td>
</tr>
<tr>
<td>Heatmap</td>
<td>Python matplotlib</td>
<td>PNG</td>
</tr>
</tbody>
</table>
<h2 id="d2-diagrams-flowcharts-architecture-control-systems-">D2 Diagrams (Flowcharts, Architecture, Control Systems)</h2>
<p>Use D2 for all structural diagrams. Always include the macaron color classes.</p>
<h3 id="template">Template</h3>
<pre><code class="lang-d2"><span class="hljs-attribute">direction</span>: right
<span class="http"><span class="hljs-attribute">style.fill</span>: "#FFF8E7"
<span class="maxima">classes: {
macaron-blue: {
<span class="hljs-built_in">style</span>.fill: <span class="hljs-string">"#A8D8EA"</span>
<span class="hljs-built_in">style</span>.stroke: <span class="hljs-string">"#7FBCD2"</span>
<span class="hljs-built_in">style</span>.<span class="hljs-built_in">border</span>-<span class="hljs-built_in">radius</span>: <span class="hljs-number">8</span>
<span class="hljs-built_in">style</span>.stroke-<span class="hljs-built_in">width</span>: <span class="hljs-number">1</span>
<span class="hljs-built_in">style</span>.<span class="hljs-built_in">font</span>-<span class="hljs-built_in">color</span>: <span class="hljs-string">"#222222"</span>
}
macaron-pink: {
<span class="hljs-built_in">style</span>.fill: <span class="hljs-string">"#FFB7B2"</span>
<span class="hljs-built_in">style</span>.stroke: <span class="hljs-string">"#E8A0A0"</span>
<span class="hljs-built_in">style</span>.<span class="hljs-built_in">border</span>-<span class="hljs-built_in">radius</span>: <span class="hljs-number">8</span>
<span class="hljs-built_in">style</span>.stroke-<span class="hljs-built_in">width</span>: <span class="hljs-number">1</span>
<span class="hljs-built_in">style</span>.<span class="hljs-built_in">font</span>-<span class="hljs-built_in">color</span>: <span class="hljs-string">"#222222"</span>
}
macaron-green: {
<span class="hljs-built_in">style</span>.fill: <span class="hljs-string">"#B5EAD7"</span>
<span class="hljs-built_in">style</span>.stroke: <span class="hljs-string">"#8FD4B8"</span>
<span class="hljs-built_in">style</span>.<span class="hljs-built_in">border</span>-<span class="hljs-built_in">radius</span>: <span class="hljs-number">8</span>
<span class="hljs-built_in">style</span>.stroke-<span class="hljs-built_in">width</span>: <span class="hljs-number">1</span>
<span class="hljs-built_in">style</span>.<span class="hljs-built_in">font</span>-<span class="hljs-built_in">color</span>: <span class="hljs-string">"#222222"</span>
}
macaron-yellow: {
<span class="hljs-built_in">style</span>.fill: <span class="hljs-string">"#FFDAC1"</span>
<span class="hljs-built_in">style</span>.stroke: <span class="hljs-string">"#E8C0A0"</span>
<span class="hljs-built_in">style</span>.<span class="hljs-built_in">border</span>-<span class="hljs-built_in">radius</span>: <span class="hljs-number">8</span>
<span class="hljs-built_in">style</span>.stroke-<span class="hljs-built_in">width</span>: <span class="hljs-number">1</span>
<span class="hljs-built_in">style</span>.<span class="hljs-built_in">font</span>-<span class="hljs-built_in">color</span>: <span class="hljs-string">"#222222"</span>
}
macaron-purple: {
<span class="hljs-built_in">style</span>.fill: <span class="hljs-string">"#C7CEEA"</span>
<span class="hljs-built_in">style</span>.stroke: <span class="hljs-string">"#A8B0D8"</span>
<span class="hljs-built_in">style</span>.<span class="hljs-built_in">border</span>-<span class="hljs-built_in">radius</span>: <span class="hljs-number">8</span>
<span class="hljs-built_in">style</span>.stroke-<span class="hljs-built_in">width</span>: <span class="hljs-number">1</span>
<span class="hljs-built_in">style</span>.<span class="hljs-built_in">font</span>-<span class="hljs-built_in">color</span>: <span class="hljs-string">"#222222"</span>
}
macaron-orange: {
<span class="hljs-built_in">style</span>.fill: <span class="hljs-string">"#FFD8A8"</span>
<span class="hljs-built_in">style</span>.stroke: <span class="hljs-string">"#E8C090"</span>
<span class="hljs-built_in">style</span>.<span class="hljs-built_in">border</span>-<span class="hljs-built_in">radius</span>: <span class="hljs-number">8</span>
<span class="hljs-built_in">style</span>.stroke-<span class="hljs-built_in">width</span>: <span class="hljs-number">1</span>
<span class="hljs-built_in">style</span>.<span class="hljs-built_in">font</span>-<span class="hljs-built_in">color</span>: <span class="hljs-string">"#222222"</span>
}
container: {
<span class="hljs-built_in">style</span>.fill: <span class="hljs-string">"#F5F0E8"</span>
<span class="hljs-built_in">style</span>.stroke: <span class="hljs-string">"#D8D0C0"</span>
<span class="hljs-built_in">style</span>.<span class="hljs-built_in">border</span>-<span class="hljs-built_in">radius</span>: <span class="hljs-number">12</span>
<span class="hljs-built_in">style</span>.stroke-<span class="hljs-built_in">width</span>: <span class="hljs-number">1</span>
}
arrow: {
<span class="hljs-built_in">style</span>.stroke: <span class="hljs-string">"#444444"</span>
<span class="hljs-built_in">style</span>.stroke-<span class="hljs-built_in">width</span>: <span class="hljs-number">1</span>
target-arrowhead: { shape: arrow; <span class="hljs-built_in">style</span>.filled: <span class="hljs-literal">true</span>; <span class="hljs-built_in">style</span>.fill: <span class="hljs-string">"#444444"</span> }
}
dashed-arrow: {
<span class="hljs-built_in">style</span>.stroke: <span class="hljs-string">"#888888"</span>
<span class="hljs-built_in">style</span>.stroke-<span class="hljs-built_in">width</span>: <span class="hljs-number">1</span>
<span class="hljs-built_in">style</span>.stroke-dash: <span class="hljs-number">3</span>
target-arrowhead: { shape: arrow; <span class="hljs-built_in">style</span>.filled: <span class="hljs-literal">true</span>; <span class="hljs-built_in">style</span>.fill: <span class="hljs-string">"#888888"</span> }
}
}
# Your nodes here
Node1: { class: macaron-blue; <span class="hljs-built_in">label</span>: 节点<span class="hljs-number">1</span> }
Node2: { class: macaron-pink; <span class="hljs-built_in">label</span>: 节点<span class="hljs-number">2</span> }
# Connections
Node1 -> Node2: { class: arrow }</span></span>
</code></pre>
<h3 id="rendering">Rendering</h3>
<pre><code class="lang-bash"># Render to PNG (recommended <span class="hljs-keyword">for</span> documents)
d2 <span class="hljs-keyword">input</span><span class="hljs-variable">.d2</span> <span class="hljs-keyword">output</span><span class="hljs-variable">.png</span>
# Render to SVG
d2 <span class="hljs-keyword">input</span><span class="hljs-variable">.d2</span> <span class="hljs-keyword">output</span><span class="hljs-variable">.svg</span>
# For PNG <span class="hljs-keyword">output</span>, Chinese text renders correctly using system fonts
# For SVG <span class="hljs-keyword">output</span> <span class="hljs-keyword">with</span> embedded fonts, <span class="hljs-keyword">use</span> the bundled STHeiti fonts:
d2 --font-regular <span class="hljs-string">"$(dirname $0)/../assets/fonts/STHeiti-Light.ttf"</span> \
--font-bold <span class="hljs-string">"$(dirname $0)/../assets/fonts/STHeiti-Medium.ttf"</span> \
<span class="hljs-keyword">input</span><span class="hljs-variable">.d2</span> <span class="hljs-keyword">output</span><span class="hljs-variable">.svg</span>
</code></pre>
<h3 id="d2-key-rules">D2 Key Rules</h3>
<ul>
<li><code>stroke-width</code> must be an integer between 0 and 15</li>
<li><code>border-radius</code> works for rounded rectangle corners</li>
<li>D2 uses straight lines with automatic rounded corners at bends (default behavior)</li>
<li>Use <code>direction: right</code> for left-to-right flow</li>
<li>Use <code>shape: circle</code> for summing junctions</li>
<li>Use <code>shape: text</code> for labels without boxes</li>
<li>Use <code>style.fill: transparent; style.stroke: transparent</code> for invisible nodes</li>
</ul>
<h2 id="matplotlib-charts-line-bar-scatter-heatmap-">Matplotlib Charts (Line, Bar, Scatter, Heatmap)</h2>
<p>Use Python matplotlib for all data visualization charts.</p>
<h3 id="template">Template</h3>
<pre><code class="lang-python"><span class="hljs-keyword">import</span> matplotlib.pyplot <span class="hljs-keyword">as</span> plt
<span class="hljs-keyword">import</span> matplotlib
<span class="hljs-keyword">import</span> numpy <span class="hljs-keyword">as</span> np
# Chinese font support
matplotlib.rcParams[<span class="hljs-string">'font.sans-serif'</span>] = [<span class="hljs-string">'Arial Unicode MS'</span>, <span class="hljs-string">'SimHei'</span>, <span class="hljs-string">'DejaVu Sans'</span>]
matplotlib.rcParams[<span class="hljs-string">'axes.unicode_minus'</span>] = False
# Macaron colors
COLORS = {
<span class="hljs-string">'blue'</span>: <span class="hljs-string">'#A8D8EA'</span>, <span class="hljs-string">'pink'</span>: <span class="hljs-string">'#FFB7B2'</span>, <span class="hljs-string">'green'</span>: <span class="hljs-string">'#B5EAD7'</span>,
<span class="hljs-string">'yellow'</span>: <span class="hljs-string">'#FFDAC1'</span>, <span class="hljs-string">'purple'</span>: <span class="hljs-string">'#C7CEEA'</span>, <span class="hljs-string">'orange'</span>: <span class="hljs-string">'#FFD8A8'</span>,
<span class="hljs-string">'bg'</span>: <span class="hljs-string">'#FFF8E7'</span>, <span class="hljs-string">'text'</span>: <span class="hljs-string">'#222222'</span>
}
fig, ax = plt.subplots(figsize=(<span class="hljs-number">10</span>, <span class="hljs-number">6</span>), facecolor=COLORS[<span class="hljs-string">'bg'</span>])
ax.set_facecolor(COLORS[<span class="hljs-string">'bg'</span>])
# Plot <span class="hljs-keyword">data</span>
ax.plot(x, y, <span class="hljs-built_in">color</span>=COLORS[<span class="hljs-string">'blue'</span>], linewidth=<span class="hljs-number">2.5</span>, label=<span class="hljs-string">'系列A'</span>)
# Styling
ax.set_xlabel(<span class="hljs-string">'X轴标签'</span>, fontsize=<span class="hljs-number">12</span>, <span class="hljs-built_in">color</span>=COLORS[<span class="hljs-string">'text'</span>])
ax.set_ylabel(<span class="hljs-string">'Y轴标签'</span>, fontsize=<span class="hljs-number">12</span>, <span class="hljs-built_in">color</span>=COLORS[<span class="hljs-string">'text'</span>])
ax.set_title(<span class="hljs-string">'图表标题'</span>, fontsize=<span class="hljs-number">14</span>, <span class="hljs-built_in">color</span>=COLORS[<span class="hljs-string">'text'</span>], fontweight=<span class="hljs-string">'bold'</span>)
ax.legend(loc=<span class="hljs-string">'best'</span>, framealpha=<span class="hljs-number">0.9</span>, facecolor=COLORS[<span class="hljs-string">'bg'</span>])
ax.grid(True, alpha=<span class="hljs-number">0.3</span>, <span class="hljs-built_in">color</span>=<span class="hljs-string">'#999999'</span>)
ax.tick_params(colors=COLORS[<span class="hljs-string">'text'</span>])
<span class="hljs-keyword">for</span> spine <span class="hljs-built_in">in</span> ax.spines.values():
spine.set_color(<span class="hljs-string">'#CCCCCC'</span>)
plt.tight_layout()
plt.savefig(<span class="hljs-string">'output.png'</span>, dpi=<span class="hljs-number">150</span>, facecolor=COLORS[<span class="hljs-string">'bg'</span>], bbox_inches=<span class="hljs-string">'tight'</span>)
</code></pre>
<h2 id="file-organization">File Organization</h2>
<p>When creating diagrams for a project:</p>
<ol>
<li>Save D2 source as <code>.d2</code> files</li>
<li>Save Python chart scripts as <code>.py</code> files</li>
<li>Output PNGs to the project's <code>figures/</code> or <code>images/</code> directory</li>
<li>Include source files alongside outputs for future editing</li>
</ol>
示例D2图表: sam3_data_engine.d2
# SAM 3 Data Engine - Horizontal Layout for Document Embedding
# Left-to-right flow optimized for landscape document pages
direction: right
classes: {
blue-box: {
style.fill: "#B8D4F0"
style.stroke: "#90B8E0"
style.border-radius: 8
style.stroke-width: 1
}
red-box: {
style.fill: "#F0B8B8"
style.stroke: "#E09090"
style.border-radius: 8
style.stroke-width: 1
}
green-box: {
style.fill: "#E8F0E8"
style.stroke: "#A0C0A0"
style.border-radius: 8
style.stroke-width: 1
}
gray-container: {
style.fill: "#F0F4F8"
style.stroke: "#D0D8E0"
style.border-radius: 12
style.stroke-width: 1
}
white-box: {
style.fill: white
style.stroke: "#8899AA"
style.border-radius: 8
style.stroke-width: 1
}
pill-blue: {
style.fill: "#B8D4F0"
style.stroke: "#90B8E0"
style.border-radius: 20
style.stroke-width: 1
}
pill-red: {
style.fill: "#F0B8B8"
style.stroke: "#E09090"
style.border-radius: 20
style.stroke-width: 1
}
arrow: {
style.stroke: "#8899AA"
style.stroke-width: 2
target-arrowhead: {
shape: arrow
style.filled: true
}
}
dashed-arrow: {
style.stroke: "#8899AA"
style.stroke-width: 2
style.stroke-dash: 5
target-arrowhead: {
shape: arrow
style.filled: true
}
}
}
# ============================================================
# NODES - All at top level for horizontal elk layout
# ============================================================
# Input Sources Container (left)
InputSources: {
class: gray-container
MediaPool: {
class: white-box
label: |md
▶ Media Pool
|
}
Ontology: {
class: white-box
label: |md
☸ Ontology
|
}
}
# Processing nodes (blue)
MineData: {
class: blue-box
label: Mine data
}
ProposeNPs: {
class: blue-box
label: Propose NPs
}
ProposeMask: {
class: blue-box
label: |md
Propose mask
SAM 3
|
}
# Flower image placeholder (top right)
Flower1: {
class: green-box
label: |md
[Flower Image]
Flower
|
}
# Legend (bottom left)
Legend: {
class: gray-container
AIModel: {
class: blue-box
label: AI model
}
Human: {
class: red-box
label: Human
}
LabelArrow: {
shape: text
label: "→ Label"
style.fill: transparent
style.stroke: transparent
}
TrainArrow: {
shape: text
label: "╌╌╌ Train"
style.fill: transparent
style.stroke: transparent
}
}
# Final annotations (bottom)
FinalAnnotations: {
class: green-box
label: |md
[Flower Image]
Flower
|
}
# Correct node (red/pink)
Correct: {
class: red-box
label: Correct
}
# Incomplete masks
IncompleteMasks: {
class: green-box
label: |md
[Flower Image]
Flower
|
}
# Verifiers Container (bottom right)
Verifiers: {
class: gray-container
AIVerifiers: {
class: pill-blue
label: AI verifiers
}
HumanVerifiers: {
class: pill-red
label: Human verifiers
}
}
# ============================================================
# CONNECTIONS
# ============================================================
# Top pipeline: InputSources -> MineData -> ProposeNPs -> ProposeMask -> Flower1
InputSources -> MineData: { class: arrow }
MineData -> ProposeNPs: { class: arrow }
ProposeNPs -> ProposeMask: { class: arrow }
ProposeMask -> Flower1: { class: arrow }
# Flower1 -> Verifiers (Candidates)
Flower1 -> Verifiers: {
class: arrow
label: Candidates
}
# Verifiers -> IncompleteMasks (dashed)
Verifiers -> IncompleteMasks: { class: dashed-arrow }
# IncompleteMasks -> Correct (Fail)
IncompleteMasks -> Correct: {
class: arrow
label: Fail
}
# Correct -> FinalAnnotations
Correct -> FinalAnnotations: {
class: arrow
label: |md
Final annotations
|
}
# Verifiers -> FinalAnnotations (Pass, dashed, bottom loop)
Verifiers -> FinalAnnotations: {
class: dashed-arrow
label: Pass
}
# Correct -> ProposeMask (Incomplete masks, dashed, left loop)
Correct -> ProposeMask: {
class: dashed-arrow
label: |md
Incomplete masks
|
}
运行效果
- 运行
d2 sam3_data_engine.d2 output.png生成流程图 - 运行Python脚本生成matplotlib数据图表
- 所有输出使用统一的马卡龙配色和奶油色背景,支持中文显示

在macOS上使用kimi-cli的plot-skill技能,通过D2和Python matplotlib创建科研/技术图表,采用统一的马卡龙配色方案和奶油色背景.
浙公网安备 33010602011771号