K-Dense-AI/scientific-agent-skills 的科技论文绘图 skill 中抄来的绘图提示词。

调用源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
import random
import urllib.request
import urllib.error
import json
import os
import ssl
import base64
import argparse
import sys
from datetime import datetime


def save_image(image_entry, output_filename):
"""
Parses various image structures (OpenRouter image_url or OpenAI URL/B64).
"""
try:
if isinstance(image_entry, dict):
if "image_url" in image_entry:
image_data = image_entry["image_url"]["url"]
else:
image_data = image_entry.get("url") or image_entry.get("b64_json")
else:
image_data = image_entry

if not image_data:
print(
"Error: Could not find image URL or Base64 data in the response entry."
)
return False

if image_data.startswith("http"):
print("Downloading image...")
ctx = ssl._create_unverified_context()
with urllib.request.urlopen(
image_data, context=ctx, timeout=30
) as response:
with open(output_filename, "wb") as f:
f.write(response.read())
else:
print("Decoding Base64 data...")
if "," in image_data:
image_data = image_data.split(",")[1]
binary_data = base64.b64decode(image_data)
with open(output_filename, "wb") as f:
f.write(binary_data)

print(f"Successfully saved to: {output_filename}")
return True

except Exception as e:
print(f"File saving failed: {e}")
return False


def call_drawing_api(prompt, model, base_url, extra_params=None):
"""
Universal caller that adapts payload based on the endpoint path.
"""
api_key = os.getenv("API_KEY")
if not api_key:
print("Error: API_KEY environment variable is not set.")
sys.exit(1)

payload = {
"model": model,
"messages": [{"role": "user", "content": prompt}],
"modalities": ["image"],
}

if extra_params:
payload.update(extra_params)

headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}",
}

req = urllib.request.Request(
base_url, data=json.dumps(payload).encode("utf-8"), headers=headers
)

ctx = ssl._create_unverified_context()

try:
print(f"Sending request to: {base_url}")
with urllib.request.urlopen(req, context=ctx, timeout=120) as response:
res_json = json.loads(response.read().decode("utf-8"))

message = res_json["choices"][0]["message"]
if "images" in message:
return message["images"][0]

print("No image data found. Full response:")
print(json.dumps(res_json, indent=2))
return None

except urllib.error.HTTPError as e:
error_body = e.read().decode()
print(f"HTTP Error {e.code}: {error_body}")
except Exception as e:
print(f"API Connection Error: {e}")
return None


def get_valid_prompt(file_path):
"""
Handles prompt acquisition with a confirmation loop.
"""
prompt_content = ""

if file_path:
try:
with open(file_path, "r", encoding="utf-8") as f:
prompt_content = f.read().strip()

if prompt_content:
print(f"\n--- Read from file [{file_path}] ---")
print(f"Content: {prompt_content}")
print("-" * 30)

confirm = (
input("Use this prompt? (Y/n, or enter 'm' to input manually): ")
.strip()
.lower()
)
if confirm in ["y", ""]:
return prompt_content
else:
print(f"Warning: File [{file_path}] is empty.")
except Exception as e:
print(f"Error reading file: {e}")

while True:
prompt_content = input("\nPlease enter your prompt manually: ").strip()
if not prompt_content:
print("Error: Prompt cannot be empty. Please try again.")
continue

print(f"\nYour input: {prompt_content}")
confirm = input("Confirm this prompt? (Y/n): ").strip().lower()
if confirm in ["y", ""]:
return prompt_content


def main():
parser = argparse.ArgumentParser(
description="Professional Universal Image Gen Script"
)
parser.add_argument("--model", required=True, help="Model")
parser.add_argument(
"--base-url", default="https://openrouter.ai/api/v1", help="Base API URL"
)
parser.add_argument("--prompt", help="Path to prompt file")
parser.add_argument("--output", help="Output filename")
parser.add_argument("--seed", type=int, help="Seed for generation")
parser.add_argument(
"--extra", help='Extra params as JSON string (e.g. \'{"size":"1024x1024"}\')'
)

args = parser.parse_args()

final_prompt = get_valid_prompt(args.prompt)

base_url = args.base_url.rstrip("/")
if "chat/completions" not in base_url:
base_url += "/chat/completions"

extra_dict = None
if args.extra:
try:
extra_dict = json.loads(args.extra)
except json.JSONDecodeError:
print("Error: --extra must be a valid JSON string.")
sys.exit(1)

if args.seed is not None:
current_seed = args.seed
else:
current_seed = random.randint(0, 10**9)
print(f"No seed provided. Generated random seed: {current_seed}")

extra_dict = json.loads(args.extra) if args.extra else {}
extra_dict["seed"] = current_seed

timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
out_file = args.output or f"IMG_{timestamp}_S{current_seed}.png"

result = call_drawing_api(final_prompt, args.model, base_url, extra_dict)
if result:
save_image(result, out_file)


if __name__ == "__main__":
main()

prompt 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
Create a high-quality scientific diagram with these requirements:

VISUAL QUALITY:
- Clean white or light background (no textures or gradients)
- High contrast for readability and printing
- Professional, publication-ready appearance
- Sharp, clear lines and text
- Adequate spacing between elements to prevent crowding

TYPOGRAPHY:
- Clear, readable sans-serif fonts (Arial, Helvetica style)
- Minimum 10pt font size for all labels
- Consistent font sizes throughout
- All text horizontal or clearly readable
- No overlapping text

SCIENTIFIC STANDARDS:
- Accurate representation of concepts
- Clear labels for all components
- Include scale bars, legends, or axes where appropriate
- Use standard scientific notation and symbols
- Include units where applicable

ACCESSIBILITY:
- Colorblind-friendly color palette (use Okabe-Ito colors if using color)
- High contrast between elements
- Redundant encoding (shapes + colors, not just colors)
- Works well in grayscale

LAYOUT:
- Logical flow (left-to-right or top-to-bottom)
- Clear visual hierarchy
- Balanced composition
- Appropriate use of whitespace
- No clutter or unnecessary decorative elements

IMPORTANT - NO FIGURE NUMBERS:
- Do NOT include "Figure 1:", "Fig. 1", or any figure numbering in the image
- Do NOT add captions or titles like "Figure: ..." at the top or bottom
- Figure numbers and captions are added separately in the document/LaTeX
- The diagram should contain only the visual content itself


USER REQUEST:

Scientific schematic diagram for Dynamic Low-Rank (DLR) BUG integrator applied to linear Radiative Transfer Equation (RTE) with macro-micro decomposition.

TOP SECTION - 'Linear RTE with Macro-Micro Decomposition':
- Equation: $f = \rho(t,x) + \varepsilon \cdot g(t,x,\Omega)$
- $\rho$: macroscopic density
- $g$: high-dimensional microscopic perturbation

MIDDLE SECTION - 'S_N Angular Discretization':
- After discretization: G is a matrix of size $N_x \times N_{\Omega}$ ($N_x$: spatial points, $N_{\Omega}$: angular directions)
- KEY FORMULA BOX (highlighted): 'Low-rank approximation: $G M \approx X S V^\top$'
- $X \in \mathbb{R}^{N_x \times r}$ (spatial basis)
- $S \in \mathbb{R}^{r \times r}$
- $V \in \mathbb{R}^{N_{\Omega} \times r}$ (angular basis)
- IMPORTANT: $M = \diag(\sqrt{w_i})$ is the diagonal matrix of square roots of angular quadrature weights

BOTTOM SECTION - 'BUG Time Integrator' flow diagram:
- Start: $X^n S^n (V^n)^\top$' at time step $t^n$
- PARALLEL FORK: K-step and L-step run SIMULTANEOUSLY (show as two parallel branches)
- MERGE: Both K and L converge into S-step
- End: $X^{n+1} S^{n+1} (V^{n+1})^\top$' at time step $t^{n+1}$

STYLE: Clean mathematical publication quality, professional sans-serif fonts, high contrast, colorblind-friendly palette, logical top-to-bottom flow."

Generate a publication-quality scientific diagram that meets all the guidelines above.