Loading...
Loading...
Compare original and translation side by side
library(ggplot2)
library(patchwork)library(ggplot2)
library(patchwork)undefinedundefinedlibrary(ggplot2)
library(cowplot)library(ggplot2)
library(cowplot)undefinedundefined#!/usr/bin/env python3
"""Legacy: Assemble multi-panel scientific figure from PNG files."""
from PIL import Image, ImageDraw, ImageFont
from pathlib import Path
def add_panel_label(img, label, position='top-left',
font_size=80, offset=(40, 40),
bg_color='white', text_color='black',
border=True):
"""
Add panel label (A, B, C) to image.
Args:
img: PIL Image object
label: Label text (e.g., 'A', 'B', 'C')
position: 'top-left', 'top-right', 'bottom-left', 'bottom-right'
font_size: Font size in pixels (80 works well for 3000px wide images)
offset: (x, y) offset from corner in pixels
bg_color: Background color for label box
text_color: Label text color
border: Whether to draw border around label box
"""
draw = ImageDraw.Draw(img)
# Try system fonts (macOS, then Linux)
try:
font = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", font_size)
except:
try:
font = ImageFont.truetype(
"/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", font_size
)
except:
font = ImageFont.load_default()
print(f"Warning: Using default font for label {label}")
# Calculate label position
x, y = offset
if 'right' in position:
bbox = draw.textbbox((0, 0), label, font=font)
text_width = bbox[2] - bbox[0]
x = img.width - text_width - offset[0]
if 'bottom' in position:
bbox = draw.textbbox((0, 0), label, font=font)
text_height = bbox[3] - bbox[1]
y = img.height - text_height - offset[1]
# Draw background box
bbox = draw.textbbox((x, y), label, font=font)
padding = 10
draw.rectangle(
[bbox[0] - padding, bbox[1] - padding,
bbox[2] + padding, bbox[3] + padding],
fill=bg_color,
outline='black' if border else None,
width=2 if border else 0
)
# Draw text
draw.text((x, y), label, fill=text_color, font=font)
return img
def assemble_vertical(input_files, output_file, labels=None,
spacing=40, dpi=300):
"""
Stack images vertically with panel labels.
Args:
input_files: List of paths to input images
output_file: Path for output image
labels: List of labels (default: A, B, C, ...)
spacing: Vertical spacing between panels in pixels
dpi: Output resolution
"""
if labels is None:
labels = [chr(65 + i) for i in range(len(input_files))] # A, B, C, ...
# Load all images
images = [Image.open(f) for f in input_files]
# Add labels
labeled = [add_panel_label(img, label)
for img, label in zip(images, labels)]
# Calculate dimensions
max_width = max(img.width for img in labeled)
total_height = sum(img.height for img in labeled) + spacing * (len(labeled) - 1)
# Create combined image
combined = Image.new('RGB', (max_width, total_height), 'white')
# Paste images
y_offset = 0
for img in labeled:
combined.paste(img, (0, y_offset))
y_offset += img.height + spacing
# Save with specified DPI
combined.save(output_file, dpi=(dpi, dpi))
print(f"✅ Created {output_file}")
print(f" Dimensions: {combined.width}×{combined.height} px at {dpi} DPI")
return output_file
def assemble_horizontal(input_files, output_file, labels=None,
spacing=40, dpi=300):
"""Stack images horizontally with panel labels."""
if labels is None:
labels = [chr(65 + i) for i in range(len(input_files))]
images = [Image.open(f) for f in input_files]
labeled = [add_panel_label(img, label)
for img, label in zip(images, labels)]
max_height = max(img.height for img in labeled)
total_width = sum(img.width for img in labeled) + spacing * (len(labeled) - 1)
combined = Image.new('RGB', (total_width, max_height), 'white')
x_offset = 0
for img in labeled:
combined.paste(img, (x_offset, 0))
x_offset += img.width + spacing
combined.save(output_file, dpi=(dpi, dpi))
print(f"✅ Created {output_file}")
print(f" Dimensions: {combined.width}×{combined.height} px at {dpi} DPI")
return output_file
def assemble_grid(input_files, output_file, rows, cols,
labels=None, spacing=40, dpi=300):
"""
Arrange images in a grid with panel labels.
Args:
rows: Number of rows
cols: Number of columns
Other args same as assemble_vertical
"""
if labels is None:
labels = [chr(65 + i) for i in range(len(input_files))]
images = [Image.open(f) for f in input_files]
labeled = [add_panel_label(img, label)
for img, label in zip(images, labels)]
# Calculate cell dimensions (use max from each row/col)
cell_width = max(img.width for img in labeled)
cell_height = max(img.height for img in labeled)
# Total dimensions
total_width = cell_width * cols + spacing * (cols - 1)
total_height = cell_height * rows + spacing * (rows - 1)
combined = Image.new('RGB', (total_width, total_height), 'white')
# Place images
for idx, img in enumerate(labeled):
if idx >= rows * cols:
break
row = idx // cols
col = idx % cols
x = col * (cell_width + spacing)
y = row * (cell_height + spacing)
combined.paste(img, (x, y))
combined.save(output_file, dpi=(dpi, dpi))
print(f"✅ Created {output_file}")
print(f" Dimensions: {combined.width}×{combined.height} px at {dpi} DPI")
return output_file
if __name__ == '__main__':
import sys
# Example usage
if len(sys.argv) < 3:
print("Usage: python assemble_figures.py <output> <layout> <input1> <input2> ...")
print(" layout: vertical, horizontal, or grid:RxC (e.g., grid:2x2)")
sys.exit(1)
output = sys.argv[1]
layout = sys.argv[2]
inputs = sys.argv[3:]
if layout == 'vertical':
assemble_vertical(inputs, output)
elif layout == 'horizontal':
assemble_horizontal(inputs, output)
elif layout.startswith('grid:'):
rows, cols = map(int, layout.split(':')[1].split('x'))
assemble_grid(inputs, output, rows, cols)
else:
print(f"Unknown layout: {layout}")
sys.exit(1)#!/usr/bin/env python3
"""Legacy: Assemble multi-panel scientific figure from PNG files."""
from PIL import Image, ImageDraw, ImageFont
from pathlib import Path
def add_panel_label(img, label, position='top-left',
font_size=80, offset=(40, 40),
bg_color='white', text_color='black',
border=True):
"""
Add panel label (A, B, C) to image.
Args:
img: PIL Image object
label: Label text (e.g., 'A', 'B', 'C')
position: 'top-left', 'top-right', 'bottom-left', 'bottom-right'
font_size: Font size in pixels (80 works well for 3000px wide images)
offset: (x, y) offset from corner in pixels
bg_color: Background color for label box
text_color: Label text color
border: Whether to draw border around label box
"""
draw = ImageDraw.Draw(img)
# Try system fonts (macOS, then Linux)
try:
font = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", font_size)
except:
try:
font = ImageFont.truetype(
"/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", font_size
)
except:
font = ImageFont.load_default()
print(f"Warning: Using default font for label {label}")
# Calculate label position
x, y = offset
if 'right' in position:
bbox = draw.textbbox((0, 0), label, font=font)
text_width = bbox[2] - bbox[0]
x = img.width - text_width - offset[0]
if 'bottom' in position:
bbox = draw.textbbox((0, 0), label, font=font)
text_height = bbox[3] - bbox[1]
y = img.height - text_height - offset[1]
# Draw background box
bbox = draw.textbbox((x, y), label, font=font)
padding = 10
draw.rectangle(
[bbox[0] - padding, bbox[1] - padding,
bbox[2] + padding, bbox[3] + padding],
fill=bg_color,
outline='black' if border else None,
width=2 if border else 0
)
# Draw text
draw.text((x, y), label, fill=text_color, font=font)
return img
def assemble_vertical(input_files, output_file, labels=None,
spacing=40, dpi=300):
"""
Stack images vertically with panel labels.
Args:
input_files: List of paths to input images
output_file: Path for output image
labels: List of labels (default: A, B, C, ...)
spacing: Vertical spacing between panels in pixels
dpi: Output resolution
"""
if labels is None:
labels = [chr(65 + i) for i in range(len(input_files))] # A, B, C, ...
# Load all images
images = [Image.open(f) for f in input_files]
# Add labels
labeled = [add_panel_label(img, label)
for img, label in zip(images, labels)]
# Calculate dimensions
max_width = max(img.width for img in labeled)
total_height = sum(img.height for img in labeled) + spacing * (len(labeled) - 1)
# Create combined image
combined = Image.new('RGB', (max_width, total_height), 'white')
# Paste images
y_offset = 0
for img in labeled:
combined.paste(img, (0, y_offset))
y_offset += img.height + spacing
# Save with specified DPI
combined.save(output_file, dpi=(dpi, dpi))
print(f"✅ Created {output_file}")
print(f" Dimensions: {combined.width}×{combined.height} px at {dpi} DPI")
return output_file
def assemble_horizontal(input_files, output_file, labels=None,
spacing=40, dpi=300):
"""Stack images horizontally with panel labels."""
if labels is None:
labels = [chr(65 + i) for i in range(len(input_files))]
images = [Image.open(f) for f in input_files]
labeled = [add_panel_label(img, label)
for img, label in zip(images, labels)]
max_height = max(img.height for img in labeled)
total_width = sum(img.width for img in labeled) + spacing * (len(labeled) - 1)
combined = Image.new('RGB', (total_width, max_height), 'white')
x_offset = 0
for img in labeled:
combined.paste(img, (x_offset, 0))
x_offset += img.width + spacing
combined.save(output_file, dpi=(dpi, dpi))
print(f"✅ Created {output_file}")
print(f" Dimensions: {combined.width}×{combined.height} px at {dpi} DPI")
return output_file
def assemble_grid(input_files, output_file, rows, cols,
labels=None, spacing=40, dpi=300):
"""
Arrange images in a grid with panel labels.
Args:
rows: Number of rows
cols: Number of columns
Other args same as assemble_vertical
"""
if labels is None:
labels = [chr(65 + i) for i in range(len(input_files))]
images = [Image.open(f) for f in input_files]
labeled = [add_panel_label(img, label)
for img, label in zip(images, labels)]
# Calculate cell dimensions (use max from each row/col)
cell_width = max(img.width for img in labeled)
cell_height = max(img.height for img in labeled)
# Total dimensions
total_width = cell_width * cols + spacing * (cols - 1)
total_height = cell_height * rows + spacing * (rows - 1)
combined = Image.new('RGB', (total_width, total_height), 'white')
# Place images
for idx, img in enumerate(labeled):
if idx >= rows * cols:
break
row = idx // cols
col = idx % cols
x = col * (cell_width + spacing)
y = row * (cell_height + spacing)
combined.paste(img, (x, y))
combined.save(output_file, dpi=(dpi, dpi))
print(f"✅ Created {output_file}")
print(f" Dimensions: {combined.width}×{combined.height} px at {dpi} DPI")
return output_file
if __name__ == '__main__':
import sys
# Example usage
if len(sys.argv) < 3:
print("Usage: python assemble_figures.py <output> <layout> <input1> <input2> ...")
print(" layout: vertical, horizontal, or grid:RxC (e.g., grid:2x2)")
sys.exit(1)
output = sys.argv[1]
layout = sys.argv[2]
inputs = sys.argv[3:]
if layout == 'vertical':
assemble_vertical(inputs, output)
elif layout == 'horizontal':
assemble_horizontal(inputs, output)
elif layout.startswith('grid:'):
rows, cols = map(int, layout.split(':')[1].split('x'))
assemble_grid(inputs, output, rows, cols)
else:
print(f"Unknown layout: {layout}")
sys.exit(1)#!/usr/bin/env Rscript#!/usr/bin/env Rscriptundefinedundefinedlibrary(cowplot)library(cowplot)undefinedundefinedlibrary(patchwork)library(patchwork)undefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedfont_size=80font_size=40font_size=160font_size=80font_size=40font_size=160position='top-left'position='top-right'position='bottom-left'position='bottom-right'position='top-left'position='top-right'position='bottom-left'position='bottom-right'spacing=40spacing=20spacing=80spacing=40spacing=20spacing=80bg_color=None, border=Falsebg_color='#f0f0f0', text_color='#333333'bg_color=None, border=Falsebg_color='#f0f0f0', text_color='#333333'font_sizepositionoffsetfont_sizepositionoffsetundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefinedundefined✅ Created figure1_efficacy.png
Dimensions: 3000×4200 px at 300 DPI
Size: 2.3 MB✅ Created figure1_efficacy.png
Dimensions: 3000×4200 px at 300 DPI
Size: 2.3 MB✅ Created Figure1_Efficacy.png
Dimensions: 3000×6080 px at 300 DPI✅ Created Figure1_Efficacy.png
Dimensions: 3000×6080 px at 300 DPI/meta-manuscript-assembly/plot-publication/figure-legends/meta-manuscript-assembly/plot-publication/figure-legendsp1 / p2theme_set(theme_minimal())align = "v"axis = "l"base_sizep1 / p2theme_set(theme_minimal())align = "v"axis = "l"base_size