
Visual Design
- 38 installs
- 186 repo stars
- Updated August 4, 2026
- aws-samples/sample-strands-agent-with-agentcore
visual-design is a Claude skill that generates charts, posters, infographics, diagrams, and artwork as PNG or PDF from Python code.
About
This skill produces visual outputs (charts, posters, infographics, diagrams, and artwork) as PNG or PDF from generated Python code. generate_chart handles data charts with matplotlib or plotly, and create_visual_design handles designs with reportlab, Pillow, or svgwrite. A developer uses it when an assistant needs to render a visual deliverable. It ships design guidance on palettes, typography, spacing, and a QA fix-verify cycle.
- Produces charts, posters, infographics, diagrams, and artwork as PNG or PDF
- generate_chart runs matplotlib/plotly code; create_visual_design uses reportlab, Pillow, or svgwrite
- Includes palettes, typography, spacing rules, and a QA fix-verify cycle
Visual Design by the numbers
- 38 all-time installs (skills.sh)
- Ranked #933 of 1,335 Generative Media skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
visual-design capabilities & compatibility
- Capabilities
- data visualization · poster design · diagram generation
- Use cases
- image generation · data analysis · ui design
- Pricing
- Free
What visual-design says it does
charts, diagrams, posters, infographics, abstract artwork, or any visual design
generate_chart: Data charts/graphs (matplotlib, plotly, bokeh) → PNG
npx skills add https://github.com/aws-samples/sample-strands-agent-with-agentcore --skill visual-designAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 38 |
|---|---|
| repo stars | ★ 186 |
| Last updated | August 4, 2026 |
| Repository | aws-samples/sample-strands-agent-with-agentcore ↗ |
What it does
Generate a chart, poster, infographic, diagram, or artwork as a PNG or PDF from an agent.
Who is it for?
Rendering data charts and designed visuals (posters, infographics, diagrams, artwork) as image or PDF output.
Skip if: Editable office documents like spreadsheets or slide decks.
When should I use this skill?
The user needs a visual output such as a chart, poster, infographic, diagram, or artwork as an image or PDF.
What you get
A PNG or PDF chart, poster, infographic, diagram, or artwork rendered from generated Python code.
- PNG chart or design
- PDF poster or infographic
By the numbers
- 2 design tools
- 8 color-palette themes documented
Files
Visual Design
Quick Reference
| Task | Tool | Guide |
|---|---|---|
| Data chart or graph | generate_chart | Read SKILL.md Design Ideas |
| Poster / infographic / art | create_visual_design | Read canvas-design.md |
| Architecture / flow diagram | create_visual_design | Read diagram-design.md |
Available Tools
generate_chart
Data visualization. Executes matplotlib/plotly code to produce chart PNGs.
python_code(str, required): Chart generation Python codeoutput_filename(str, required):.pngfilename
create_visual_design
Visual design creation: posters, infographics, artwork, diagrams. Uses reportlab, Pillow, svgwrite, or any available library.
python_code(str, required): Design generation Python codeoutput_filename(str, required):.pngor.pdffilename
Available Libraries
| Purpose | Libraries | Output | Notes |
|---|---|---|---|
| Data charts | matplotlib, plotly, bokeh | PNG | Best for charts |
| PDF design | reportlab, fpdf | Full control | |
| Image design | Pillow + fonttools | PNG | Best for PNG designs |
| Vector graphics | svgwrite → svglib + renderPDF | SVG → PDF | SVG→PNG NOT supported (no renderPM) |
| Image processing | Wand (ImageMagick), opencv-python | PNG | Check availability first |
IMPORTANT: For PNG output, use Pillow or matplotlib. Do NOT use svgwrite→renderPM (rlPyCairo is unavailable).
Design Workflow
Data Charts (generate_chart)
1. Identify data structure and choose appropriate chart type 2. Select color palette (see Design Ideas below) 3. Write code with plt.savefig(filename, dpi=300, bbox_inches='tight') 4. Review the generated chart
Visual Design (create_visual_design)
1. Establish design concept/philosophy (internally) 2. Follow the process in canvas-design.md 3. Select appropriate library and write code 4. Save: reportlab canvas.save(), Pillow image.save(), matplotlib plt.savefig() 5. Review output and refine
Design Ideas
Color Palettes
| Theme | Primary | Accent | Background |
|---|---|---|---|
| Midnight Executive | 1E2761 | 408EC6 | 0D1B2A |
| Forest & Moss | 2C5F2D | 97BC62 | 1A1A1A |
| Coral Energy | F96167 | F9E795 | 2F3C7E |
| Ocean Gradient | 065A82 | 1B9AAA | 021B29 |
| Charcoal Minimal | 36454F | E8E8E8 | 1C1C1E |
| Cherry Bold | 990011 | FCF6F5 | 150E11 |
| Sage Calm | 84B59F | 69A297 | 2D3A2D |
| Warm Terracotta | B85042 | E7E8D1 | 2A1F1C |
Typography
Prefer thin/light fonts. Minimize text in designs.
| Element | Size | Style |
|---|---|---|
| Main title | 48-72pt | Bold or Thin |
| Subtext | 14-18pt | Light |
| Labels/captions | 8-12pt | Regular, muted |
Text-to-Canvas Balance (IMPORTANT):
- Text size must be proportional to the overall canvas and surrounding design elements
- Common mistake: text that is too small relative to the canvas, making it unreadable at normal viewing distance
- Rule of thumb: if you need to zoom in to read it, it's too small
- Titles should command attention — when in doubt, go larger
- Labels/captions should be clearly legible, not decorative afterthoughts
- Test: mentally shrink the output to 50% — all text should still be readable
Spacing & Composition
- Generous margins (minimum 10% of canvas)
- Consistent spacing between elements
- No overlapping; all elements within canvas bounds
- Visual hierarchy: convey importance via size, color, position
Avoid
- Elements flush to canvas edges (insufficient margins)
- Overlapping elements
- Too many colors (stick to 3-4)
- Excessive text — visual elements are the focus
- Default matplotlib styles without customization
Code Requirements
- Code must save a file to disk
- Use the exact
output_filenameprovided - PNG:
dpi=300or higher recommended - PDF: A4 or Letter size recommended
- For Korean text: configure appropriate fonts
QA
Assume there are problems and look for them.
1. Review the generated image/PDF 2. Check for overlapping elements, clipped text, insufficient margins 3. Verify sufficient color contrast 4. If issues found, fix the code and regenerate 5. Complete at least one fix-verify cycle before finishing
UI Guidance (from tools-config)
Tool Selection:
- generate_chart: Data charts/graphs (matplotlib, plotly, bokeh) → PNG
- create_visual_design: Posters, infographics, artwork, flow diagrams (reportlab, Pillow, svgwrite) → PNG or PDF
Code Requirements:
- Charts: plt.savefig(filename, dpi=300, bbox_inches='tight')
- PDF designs: canvas.save() (reportlab) or equivalent
- Image designs: image.save(filename) (Pillow)
- PNG: dpi=300+ recommended
- PDF: A4 or Letter size recommended
Canvas Design Guide
Reference for create_visual_design tool. Follow this process for posters, infographics, artwork, and flow diagrams.
Design Philosophy Approach
Every visual design follows a 2-step process:
Step 1: Establish a Design Philosophy
Before writing any code, define the visual intent in 4-6 internal sentences covering:
- Space & Form: How will negative space interact with shapes? Dense or sparse?
- Color & Texture: What emotional tone? What palette from SKILL.md?
- Scale & Rhythm: Are elements uniform or varied? Is there visual rhythm?
- Composition & Balance: Symmetric or asymmetric? Where does the eye travel?
Step 2: Name the Movement
Give the design a 1-2 word movement name that captures its aesthetic:
- Examples: "Brutalist Joy", "Chromatic Silence", "Grid Meditation", "Neon Geometry"
- This name guides every decision — when in doubt, ask "does this serve the movement?"
Craftsmanship Standards
Build as if a meticulous expert craftsperson is creating a gallery-quality piece:
- Every pixel/point placement is intentional
- Alignments are exact, not approximate
- Colors are chosen with purpose, not randomly
- Spacing is consistent and mathematically grounded
Text Principles
Text in visual design is a visual element, not content:
- Minimal: Use as few words as possible
- Visual accent: Text serves composition, not information delivery
- Typographic hierarchy: Size and weight create visual rhythm
- Never dominant: Text should not compete with visual elements for attention
- Proportional to canvas: Text must be sized relative to the overall canvas and surrounding elements. A common failure is text that looks fine in code but renders far too small on the actual canvas. When in doubt, scale up. If you mentally shrink the output to 50%, every text element should still be legible.
Subtle Reference
When the design has a subject (e.g., "AI poster", "data science infographic"):
- Reflect the theme through metaphor, not literal depiction
- Use abstract forms that evoke the subject
- Let the viewer discover meaning rather than stating it
- Geometric patterns, color relationships, and spatial arrangements carry meaning
Canvas Production Principles
Repetition & Pattern
- Systematic repetition creates visual rhythm
- Grids, arrays, and regular intervals provide structure
- Variation within repetition adds interest without chaos
Perfect Geometry
- Circles are perfect circles, lines are crisp
- Use mathematical relationships for positioning (golden ratio, rule of thirds)
- Consistent border radii, stroke widths, and corner treatments
Systematic Observation
- Every element relates to at least one other element
- Alignment guides connect disparate parts
- Color echoes across the composition create unity
Refinement Process
Two-pass minimum:
First Pass: Structure
- Establish the composition grid
- Place primary elements
- Set color palette application
- Define the visual hierarchy
Second Pass: Polish
- Refine spacing (adjust by 1-2px/pt for perfection)
- Check all alignments
- Verify color contrast and readability
- Ensure nothing bleeds off canvas
- Priority: refine existing composition over adding new elements
Library Save Patterns
ReportLab (PDF)
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
c = canvas.Canvas(output_filename, pagesize=A4)
width, height = A4
# ... drawing commands ...
c.save()Pillow (PNG)
from PIL import Image, ImageDraw, ImageFont
img = Image.new('RGB', (3000, 2000), color='#0D1B2A')
draw = ImageDraw.Draw(img)
# ... drawing commands ...
img.save(output_filename, dpi=(300, 300))SVGWrite → PDF (works)
import svgwrite
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPDF
dwg = svgwrite.Drawing('temp.svg', size=('800px', '600px'))
# ... drawing commands ...
dwg.save()
drawing = svg2rlg('temp.svg')
renderPDF.drawToFile(drawing, output_filename)SVGWrite → PNG (caution)
renderPM (rlPyCairo) is NOT available. For PNG output, prefer Pillow or matplotlib directly instead of SVG conversion. See library-reference.md for fallback chains.
matplotlib (non-chart graphics)
import matplotlib.pyplot as plt
import matplotlib.patches as patches
fig, ax = plt.subplots(figsize=(20, 14))
ax.set_xlim(0, 100)
ax.set_ylim(0, 70)
ax.axis('off')
# ... patches, artists, text ...
plt.savefig(output_filename, dpi=300, bbox_inches='tight',
facecolor=fig.get_facecolor(), edgecolor='none')Canvas Sizes
| Format | Recommended Size | Use Case |
|---|---|---|
| Poster (PNG) | 3000x4200px | Print-ready A3 portrait |
| Infographic (PNG) | 2400x4800px | Tall-scroll infographic |
| Landscape (PNG) | 3840x2160px | 4K presentation/wallpaper |
| Document (PDF) | A4 (595x842pt) | Standard document |
| Slide (PNG) | 1920x1080px | Presentation slide |
Diagram Design Guide
Technical diagrams (architecture, flow, system structure) reference. Supplements canvas-design.md with practical patterns from real iterations.
Rendering Engine: SVG First
matplotlib is for charts. For box-arrow diagrams, use svgwrite + cairosvg/wand.
import svgwrite, os
try:
import cairosvg; HC = True
except: HC = False
try:
from wand.image import Image as WI; HW = True
except: HW = False
dwg = svgwrite.Drawing('temp.svg', size=(f'{W}px', f'{H}px'),
viewBox=f'0 0 {W} {H}')
# ... draw ...
dwg.save()
if HC:
cairosvg.svg2png(url='temp.svg', write_to=output_filename,
output_width=W*2, output_height=H*2) # 2x for Retina
elif HW:
with WI(filename='temp.svg', resolution=300) as img:
img.save(filename=output_filename)
os.remove('temp.svg') # Clean upText Vertical Centering
SVG dominant_baseline is inconsistent across renderers. Use manual offset:
def tx(x, y, text, fs=14, fw='normal', fl='#333', a='middle'):
"""y = visual center. Add fs*0.35 for baseline correction."""
dwg.add(dwg.text(text, insert=(x, y + fs * 0.35),
font_size=f'{fs}px', font_weight=fw, fill=fl,
text_anchor=a, font_family='Helvetica, Arial, sans-serif'))
def tx_box(bx, by, bw, bh, text, **kwargs):
"""Center text inside a box."""
tx(bx + bw/2, by + bh/2, text, **kwargs)Why 0.35: SVG text y = baseline. Cap height ≈ 70% of font_size. Half of that = 35%. Adjust 0.3–0.4 for different fonts.
Canvas Size: Derive from Content
Do NOT pick canvas size first. Calculate from content bounds:
sk_xs = [RX_START + i * SK_GAP for i in range(num_cols)]
RIGHT_EDGE = sk_xs[-1] + BOX_W + PADDING
CANVAS_PAD = 18
W = RIGHT_EDGE + CANVAS_PAD
# Same for height: last element bottom + CANVAS_PADAlignment: Shared Coordinate Variables
# Row coordinates — all boxes on same row share same y
ROW_L2_Y = 27
ROW_L3_Y = 140
BOX_H = 42 # Uniform height
# Column coordinates — array-driven
sk_xs = [RX_START + i * SK_GAP for i in range(4)]
for i in range(4):
rr(sk_xs[i], ROW_L2_Y, SK_W, BOX_H, ...)Never hardcode repeated coordinates. One variable per row/column.
Arrow Patterns
Straight horizontal
def arrow_h(x1, y, x2, color, label=None, label_offset=-12):
ln(x1, y, x2-4, y, color, sw=2.5)
tri(x2-4, y, color, 10, 'right')
if label:
tx((x1+x2)/2, y + label_offset, label, fs=14, fw='bold', fl=color)L-shaped (bend)
bend_x = start_x + 22
ln(start_x, start_y, bend_x, start_y, color) # horizontal
ln(bend_x, start_y, bend_x, target_y, color) # vertical
ln(bend_x, target_y, target_x, target_y, color) # horizontal
tri(target_x, target_y, color, 10) # arrowheadLabel placement
- Horizontal arrow: above (y - 12)
- Vertical arrow: right side (x + 12)
- L-shaped: above last horizontal segment
- Match label color to arrow color
Line styles
- Solid arrow: active call/access (Agent → Service)
- Dashed line: containment/belongs-to (Parent ⊃ Child)
dwg.add(dwg.line((x1, y1), (x2, y2),
stroke='#AAA', stroke_width=1.5, stroke_dasharray='5,4'))Systematic Repeated Elements
Separate data from layout:
skills = ['web-search', 'visual-design', 'word-docs', 'code-interp']
skill_resources = [['scripts.py'], ['design.md', 'eval.py'], ['tmpl.js'], ['config.json']]
sk_xs = [RX_START + i * SK_GAP for i in range(len(skills))]
for i, (name, resources) in enumerate(zip(skills, skill_resources)):
sx = sk_xs[i]
rr(sx, ROW_Y, SK_W, BOX_H, bg, bd)
tx_box(sx, ROW_Y, SK_W, BOX_H, name, fs=13)
for j, rname in enumerate(resources):
ry = res_start_y + j * (res_h + res_gap)
rr(sx, ry, SK_W, res_h, rbg, rbd)Color Tone Matching
When matching a reference style, check these dimensions:
| Dimension | Typical range | Example |
|---|---|---|
| Saturation | 20-35% (pastel) | Muted, not vivid |
| Lightness | BG 90%+, Box 80-90%, Text 25-40% | |
| Temperature | Warm (beige/olive) or Cool (blue-gray) | |
| Border contrast | Fill color darkened 15-25% |
Rules:
- Same role = same color (e.g., all SKILL.md boxes are pink)
- Regions use semi-transparent backgrounds for grouping (opacity 0.6–0.85)
- Text color = darkened version of box fill
Margin Checklist
After each version, verify:
- Canvas edges: 15-20px padding all sides
- Region internal padding: 12-16px top/bottom, 14-20px left/right
- Box spacing: uniform within rows (use SK_GAP variable)
- Canvas bottom: last element + 15-20px = canvas height
Canvas Size Guide
| Complexity | Size | Example |
|---|---|---|
| Simple (3-5 boxes) | 600-800 × 200-300 | Single flow |
| Medium (6-15 boxes) | 800-1200 × 300-500 | Architecture overview |
| Complex (15+ boxes) | 1200-1600 × 500-800 | Detailed system structure |
Use these as starting estimates, then derive final size from content (see above).
Library Reference
Technical API patterns for visual design tools. Code examples for each library available in Code Interpreter.
ReportLab
Canvas Basics
from reportlab.lib.pagesizes import A4, letter
from reportlab.lib.units import inch, cm, mm
from reportlab.pdfgen import canvas
from reportlab.lib.colors import HexColor, Color
c = canvas.Canvas(output_filename, pagesize=A4)
w, h = A4 # 595.27, 841.89 pointsShapes
# Rectangle
c.setFillColor(HexColor('#1E2761'))
c.rect(x, y, width, height, fill=1, stroke=0)
# Rounded rectangle
c.roundRect(x, y, width, height, radius=10, fill=1, stroke=0)
# Circle
c.circle(cx, cy, radius, fill=1, stroke=0)
# Line
c.setStrokeColor(HexColor('#408EC6'))
c.setLineWidth(2)
c.line(x1, y1, x2, y2)
# Bezier curve
c.bezier(x1, y1, cx1, cy1, cx2, cy2, x2, y2)Text
# Simple text
c.setFont("Helvetica-Bold", 36)
c.setFillColor(HexColor('#FFFFFF'))
c.drawString(x, y, "Title Text")
# Centered text
c.drawCentredString(w/2, y, "Centered Title")
# Right-aligned text
c.drawRightString(w - 50, y, "Right Text")Font Registration
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
pdfmetrics.registerFont(TTFont('CustomFont', '/path/to/font.ttf'))
c.setFont('CustomFont', 24)Gradients
from reportlab.lib.colors import linearlyInterpolatedColor
# Manual gradient via thin rectangles
steps = 100
for i in range(steps):
ratio = i / steps
color = linearlyInterpolatedColor(
HexColor('#065A82'), HexColor('#1B9AAA'),
0, 1, ratio
)
c.setFillColor(color)
c.rect(0, h * ratio, w, h / steps + 1, fill=1, stroke=0)Transparency
c.saveState()
c.setFillAlpha(0.5)
c.setFillColor(HexColor('#408EC6'))
c.circle(200, 400, 80, fill=1, stroke=0)
c.restoreState()Clipping
p = c.beginPath()
p.circle(200, 400, 100)
c.clipPath(p, stroke=0)
# Everything drawn after this is clipped to the circle---
Pillow
Image Creation
from PIL import Image, ImageDraw, ImageFont, ImageFilter
img = Image.new('RGBA', (3000, 2000), (13, 27, 42, 255))
draw = ImageDraw.Draw(img)Shapes
# Rectangle
draw.rectangle([x1, y1, x2, y2], fill='#1E2761', outline='#408EC6', width=2)
# Rounded rectangle
draw.rounded_rectangle([x1, y1, x2, y2], radius=20, fill='#1E2761')
# Circle / ellipse
draw.ellipse([x-r, y-r, x+r, y+r], fill='#408EC6')
# Line
draw.line([(x1, y1), (x2, y2)], fill='#E8E8E8', width=3)
# Polygon
draw.polygon([(x1, y1), (x2, y2), (x3, y3)], fill='#97BC62')Text
# Load font (check available fonts first)
try:
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 72)
except:
font = ImageFont.load_default()
draw.text((x, y), "Title", fill='#FFFFFF', font=font)
# Centered text
bbox = draw.textbbox((0, 0), "Title", font=font)
text_w = bbox[2] - bbox[0]
draw.text(((img.width - text_w) / 2, y), "Title", fill='#FFFFFF', font=font)Alpha Compositing
# Create overlay with transparency
overlay = Image.new('RGBA', img.size, (0, 0, 0, 0))
overlay_draw = ImageDraw.Draw(overlay)
overlay_draw.rectangle([0, 0, 800, 600], fill=(30, 39, 97, 128)) # 50% alpha
img = Image.alpha_composite(img, overlay)Filters
blurred = img.filter(ImageFilter.GaussianBlur(radius=5))
sharpened = img.filter(ImageFilter.SHARPEN)Save
# For RGBA images, convert to RGB before saving as PNG
if img.mode == 'RGBA':
bg = Image.new('RGB', img.size, (255, 255, 255))
bg.paste(img, mask=img.split()[3])
bg.save(output_filename, dpi=(300, 300))
else:
img.save(output_filename, dpi=(300, 300))---
SVGWrite
Drawing Creation
import svgwrite
dwg = svgwrite.Drawing('temp.svg', size=('800px', '600px'),
viewBox='0 0 800 600')Basic Shapes
# Rectangle
dwg.add(dwg.rect(insert=(10, 10), size=(200, 100),
fill='#1E2761', stroke='#408EC6', stroke_width=2))
# Circle
dwg.add(dwg.circle(center=(400, 300), r=80, fill='#408EC6'))
# Line
dwg.add(dwg.line(start=(0, 0), end=(800, 600),
stroke='#E8E8E8', stroke_width=2))
# Polygon
dwg.add(dwg.polygon(points=[(100, 100), (200, 50), (300, 100)],
fill='#97BC62'))Text
dwg.add(dwg.text('Title', insert=(400, 50),
font_size='36px', font_family='Helvetica',
fill='#FFFFFF', text_anchor='middle'))Patterns & Repetition
# Create a pattern
pattern = dwg.defs.add(dwg.pattern(id='dots', size=(20, 20),
patternUnits='userSpaceOnUse'))
pattern.add(dwg.circle(center=(10, 10), r=3, fill='#408EC6'))
dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'),
fill='url(#dots)'))SVG Output & Conversion
IMPORTANT: renderPM (rlPyCairo) is NOT available in Code Interpreter. Do NOT use renderPM.drawToPIL() or renderPM.drawToFile() for PNG conversion.
SVG → PDF (works):
dwg.save()
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPDF
drawing = svg2rlg('temp.svg')
renderPDF.drawToFile(drawing, output_filename)SVG → PNG — use one of these fallback chains:
dwg.save()
# Option 1: cairosvg (preferred if available)
try:
import cairosvg
cairosvg.svg2png(url='temp.svg', write_to=output_filename,
output_width=3000) # Scale up for high DPI
print("Converted with cairosvg")
except ImportError:
pass
# Option 2: Wand (ImageMagick binding)
try:
from wand.image import Image as WandImage
with WandImage(filename='temp.svg') as img:
img.format = 'png'
img.save(filename=output_filename)
print("Converted with Wand")
except ImportError:
pass
# Option 3: SVG → PDF → PNG via Pillow (always works)
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPDF
from pdf2image import convert_from_path # or use Pillow + fitz
drawing = svg2rlg('temp.svg')
renderPDF.drawToFile(drawing, 'temp.pdf')
from PIL import Image
# If pdf2image is available:
try:
from pdf2image import convert_from_path
images = convert_from_path('temp.pdf', dpi=300)
images[0].save(output_filename)
print("Converted via SVG→PDF→PNG")
except ImportError:
print("pdf2image not available")Recommended approach: If you need PNG output, prefer Pillow or matplotlib directly instead of the SVG→PNG conversion chain. SVGWrite is best when PDF is the final format.
---
matplotlib (Advanced Graphics)
Non-Chart Graphics with Patches
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.collections import PatchCollection
fig, ax = plt.subplots(figsize=(20, 14))
fig.set_facecolor('#0D1B2A')
ax.set_facecolor('#0D1B2A')
ax.set_xlim(0, 100)
ax.set_ylim(0, 70)
ax.axis('off')
# Rectangle
rect = patches.FancyBboxPatch((10, 10), 30, 20,
boxstyle='round,pad=0.5',
facecolor='#1E2761', edgecolor='#408EC6')
ax.add_patch(rect)
# Circle
circle = patches.Circle((60, 40), 10, facecolor='#408EC6', alpha=0.7)
ax.add_patch(circle)
# Arrow
ax.annotate('', xy=(70, 40), xytext=(45, 25),
arrowprops=dict(arrowstyle='->', color='#E8E8E8', lw=2))
# Text
ax.text(50, 65, 'Title', fontsize=28, color='white',
ha='center', va='center', fontweight='bold')Custom Styles
plt.rcParams.update({
'figure.facecolor': '#0D1B2A',
'axes.facecolor': '#0D1B2A',
'text.color': '#E8E8E8',
'axes.labelcolor': '#E8E8E8',
'xtick.color': '#E8E8E8',
'ytick.color': '#E8E8E8',
})Save with Background
plt.savefig(output_filename, dpi=300, bbox_inches='tight',
facecolor=fig.get_facecolor(), edgecolor='none',
pad_inches=0.1)---
fonttools — Font Discovery
List Available Fonts
import os
import glob
font_dirs = [
'/usr/share/fonts',
'/usr/local/share/fonts',
os.path.expanduser('~/.fonts'),
]
fonts = []
for d in font_dirs:
fonts.extend(glob.glob(os.path.join(d, '**/*.ttf'), recursive=True))
fonts.extend(glob.glob(os.path.join(d, '**/*.otf'), recursive=True))
for f in sorted(fonts):
print(os.path.basename(f))Inspect Font Properties
from fontTools.ttLib import TTFont
font = TTFont('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf')
name_table = font['name']
for record in name_table.names:
if record.nameID in (1, 2, 4): # Family, Style, Full Name
print(f"{record.nameID}: {record.toUnicode()}")Common Code Interpreter Fonts
Typically available in Bedrock Code Interpreter:
- DejaVu Sans / DejaVu Serif / DejaVu Sans Mono
- Liberation Sans / Liberation Serif / Liberation Mono
- Noto Sans (may include CJK variants)
Always verify with the font discovery code above before assuming availability.
Related skills
FAQ
Which tool for charts vs designs?
generate_chart for data charts (matplotlib/plotly/bokeh); create_visual_design for posters, infographics, artwork, and diagrams.
What output formats?
PNG or PDF; for PNG use Pillow or matplotlib (svgwrite to renderPM is unavailable).