R: Temas e estilos do R ggplot2
Última atualização: 2026-08-26
O tema padrão
theme_gray()do ggplot2 já é bastante bom, mas, para criar gráficos com “qualidade de publicação”, você precisará ajustar o tema. Nesta lição, vamos explorar o sistema de temas do ggplot2: desde os 8 temas integrados e o ajuste fino comtheme()atélabsescale, chegando à saída em alta resolução comggsave.
Ao concluir esta lição, você será capaz de ajustar qualquer gráfico do ggplot2 de acordo com os padrões de “prontidão para publicação” — com controle total sobre o texto, as cores, as legendas, as margens e os eixos.
1. O que você vai aprender
- 8 temas integrados do ggplot2
- árvore de elementos do
theme()(element_text/line/rect) - rótulo completo de labs()
- mapeamento de cores de escala/preenchimento
- Modelos de temas (ggthemes / hrbrthemes)
- ggsave() Salvar em alta definição
- Prático: Personalizando gráficos com qualidade de publicação
2. A história de um “gráfico profissional”
(1) Problema: a imagem padrão parece muito “escolar”
Bob criou um gráfico usando o ggplot2, e o gerente disse: “Esse é um relatório para investidores — está muito simples.”
(2) Opções de visualização do ggplot2
library(ggplot2)
library(hrbrthemes) # Professional Theme Packages
p <- ggplot(sales, aes(x = quarter, y = sales, color = city, group = city)) +
geom_line(linewidth = 1.2) +
geom_point(size = 3) +
scale_color_brewer(palette = "Set1") +
labs(
title = "2024 Q1-Q4 Sales Trends",
subtitle = "Data Source: Sales System | Chart: Analyst Team",
caption = "Unit: 10,000 yuan",
x = "Quarter", y = "Sales (10,000 yuan)",
color = "City"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 16),
plot.subtitle = element_text(color = "gray50"),
legend.position = "top",
panel.grid.minor = element_blank()
)
ggsave("professional_report.png", p, width = 10, height = 6, dpi = 300)
3 linhas de código → gráficos com qualidade de publicação.
3. 8 temas integrados
(1) Comparação de temas
| Tema | Estilo | Situações adequadas |
|---|---|---|
theme_gray() |
Padrão (fundo cinza) | Geral |
theme_bw() |
Preto e branco | Artigo acadêmico |
theme_minimal() |
Minimalista (Mais utilizado) | Relatórios/Apresentações |
theme_classic() |
Clássico (sem grade) | Acadêmico |
theme_void() |
Em branco | Mapa/Diagrama |
theme_light() |
Fundo claro | Demonstração |
theme_dark() |
Fundo escuro | Tema escuro |
theme_test() |
Para testes | Depuração |
(2) Comparação na prática
p <- ggplot(mtcars, aes(wt, mpg)) + geom_point()
p + theme_gray() # Default
p + theme_minimal() # Minimalism
p + theme_bw() # Black and White
p + theme_classic() # Classic
p + theme_light() # Light-colored
p + theme_dark() # Dark
p + theme_void() # Blank
Tamanho da base / Família da base
# Set the font size globally
p + theme_minimal(base_size = 14)
# Set the Global Font
p + theme_minimal(base_family = "SimHei") # Chinese
4. Árvore de elementos da função theme()
(1) Estrutura do elemento
graph TB
A[theme Element] --> B[plot Full Image]
A --> C[axis Coordinate Axes]
A --> D[legend Legend]
A --> E[panel Panel]
A --> F[strip Facet Labels]
A --> G[title Title]
B --> H[plot.title]
B --> I[plot.background]
C --> J[axis.title]
C --> K[axis.text]
C --> L[axis.line]
D --> M[legend.title]
D --> N[legend.text]
D --> O[legend.position]
E --> P[panel.background]
E --> Q[panel.grid]
F --> R[strip.text]
F --> S[strip.background]
style A fill:#fff3cd
style B fill:#cce5ff
style C fill:#d4edda
style D fill:#f8d7da
style E fill:#e1d4ff
style F fill:#ffe1e1
style G fill:#e1ffe1
(2) 4 tipos de funções element_
| Função | Finalidade | Utilizado para |
|---|---|---|
element_text() |
Texto | Títulos, rótulos dos eixos, texto da escala |
element_line() |
Linhas | Linhas de grade, linhas de eixo |
element_rect() |
Retângulo | Fundo, Borda, Painel |
element_blank() |
Ocultar | Qualquer elemento |
(3) Parâmetro de texto da função element_text()
theme(
plot.title = element_text(
size = 16, # Font size
face = "bold", # Bold/italics (plain/bold/italic/bold.italic)
color = "blue", # Color
family = "SimHei",# Font
hjust = 0.5, # Horizontal Alignment (0=left, 1=right, 0.5=center)
vjust = 0.5 # Vertical Alignment
)
)
(4) Parâmetros da função element_line() para linhas
theme(
panel.grid.major = element_line(
color = "gray80",
linewidth = 0.5,
linetype = "dashed" # solid/dashed/dotted
),
panel.grid.minor = element_blank(), # Hide Secondary Grid
axis.line = element_line(color = "black", linewidth = 0.8)
)
(5) Parâmetro Rectangle da função element_rect()
theme(
panel.background = element_rect(
fill = "lightyellow",
color = "black",
linewidth = 0.5
),
plot.background = element_rect(fill = "white")
)
(6) element_blank() Ocultar
theme(
panel.grid = element_blank(), # Hide All Grids
axis.ticks = element_blank(), # Hide Scale
legend.position = "none" # Hide Legend (Note: No element_blank)
)
5. Aperfeiçoamento de temas comuns
(1) Tamanho do texto
p + theme(
plot.title = element_text(size = 18, face = "bold"),
plot.subtitle = element_text(size = 12, color = "gray50"),
axis.title = element_text(size = 12),
axis.text = element_text(size = 10),
legend.title = element_text(size = 11),
legend.text = element_text(size = 10)
)
(2) Linhas de grade
p + theme(
panel.grid.major = element_line(color = "gray90"),
panel.grid.minor = element_blank(), # Hide Secondary Grid (More concise)
panel.border = element_rect(color = "black", fill = NA, linewidth = 0.5)
)
(3) Localização da legenda
# 4 every corner
p + theme(legend.position = "top")
p + theme(legend.position = "bottom")
p + theme(legend.position = "left")
p + theme(legend.position = "right")
# Hide
p + theme(legend.position = "none")
# Coordinate Positioning (In the figure)
p + theme(legend.position = c(0.8, 0.2)) # 80% x, 20% y
(4) Eixos de coordenadas
p + theme(
axis.line = element_line(color = "black", linewidth = 0.8),
axis.ticks = element_line(color = "black"),
axis.title.x = element_text(margin = margin(t = 10)), # X Move the axis title down
axis.title.y = element_text(margin = margin(r = 10)) # Y Shift the axis title to the left
)
6. Documentação completa para labs()
(1) Todas as tags
p + labs(
title = "Main Title",
subtitle = "Subtitle",
caption = "Data Sources",
x = "X Axis",
y = "Y Axis",
color = "Color Mapping", # Corresponding aes(color)
fill = "Fill Mapping", # Corresponding aes(fill)
shape = "Shape Mapping",
size = "Size Mapping"
)
(2) Tags de fórmulas matemáticas
# For use in formulas quote() or expression
p + labs(
x = quote(x[i]),
y = expression(paste("Concentration (", mu, "g/mL)"))
)
7. Cores de scale_color / scale_fill
(1) Cores distintas (variáveis categóricas)
# 1. Specify manually
p + scale_color_manual(values = c("red", "blue", "green", "orange"))
# 2. ColorBrewer Color Palette
p + scale_color_brewer(palette = "Set1") # Classic 9 colors
p + scale_color_brewer(palette = "Set2") # Gentle 8 colors
p + scale_color_brewer(palette = "Dark2") # Dark 8 colors
p + scale_color_brewer(palette = "Pastel1") # Light-colored 9 colors
# 3. viridis (Color-blind-friendly, Recommended)
library(viridis)
p + scale_color_viridis_d() # Discrete
p + scale_color_viridis_c() # Consecutive
(2) Cores contínuas (variáveis contínuas)
# Gradient
p + scale_color_gradient(low = "blue", high = "red")
p + scale_color_gradient2(low = "blue", mid = "white", high = "red", midpoint = 0)
p + scale_color_gradientn(colours = rainbow(7))
(3) Aplicação prática: esquemas de cores profissionais
# 4 Class Classification
p + scale_color_brewer(palette = "Set1")
# 8 Class Classification
p + scale_color_brewer(palette = "Set2")
# Color-blind-friendly
p + scale_color_viridis_d()
# Academic/Serious
p + scale_color_manual(values = c("#1f77b4", "#ff7f0e", "#2ca02c"))
8. Pacotes de temas especializados
(1) 8 temas do ggthemes
install.packages("ggthemes")
library(ggthemes)
p + theme_economist() # The Economist
p + theme_wsj() # The Wall Street Journal
p + theme_fivethirtyeight() # FiveThirtyEight
p + theme_hc() # Highcharts
p + theme_tufte() # Tufte Minimalism
p + theme_stata() # Stata
p + theme_solarized() # Solarized
p + theme_excel() # Excel Style
(2) Temas comerciais da hrbrthemes
install.packages("hrbrthemes")
library(hrbrthemes)
p + theme_ipsum() # ipsum Typographic Style
p + theme_ft_rc() # The Financial Times
(3) Temas personalizados (Defina uma vez, use em qualquer lugar)
# Custom Themes
my_theme <- theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 14),
panel.grid.minor = element_blank(),
legend.position = "bottom"
)
# Global Use
ggplot(df, aes(x, y)) + geom_point() + my_theme
9. ggsave() Salvar em alta definição
(1) 4 parâmetros principais
ggsave(
filename, # File Name
plot = last_plot(), # Graph Object (Default: Last Image)
width = 8, # Width
height = 6, # High
units = "in", # Unit in/cm/mm
dpi = 300 # Resolution
)
(2) Aplicação prática
# PNG Printing Standard (300 dpi)
ggsave("report.png", width = 8, height = 6, dpi = 300)
# High-Definition Screen (150 dpi)
ggsave("screen.png", width = 1920, height = 1080, units = "px", dpi = 150)
# PDF For a thesis (Vector)
ggsave("paper.pdf", width = 8, height = 6)
# Chinese Title (Avoid garbled characters)
ggsave("Chinese.png", width = 8, height = 6, dpi = 300)
(3) Vários formatos
| Formato | Extensão | Finalidade |
|---|---|---|
| PNG | .png |
Web/Documentos (Mais comum) |
.pdf |
Tese (Vector) | |
| SVG | .svg |
Gráficos vetoriais para a web |
| JPEG | .jpg |
Foto (não recomendado para gráficos) |
| TIFF | .tiff |
Impressão |
# Vector Graphics (Unlimited Clear Zoom)
ggsave("vector.svg", width = 8, height = 6)
ggsave("vector.pdf", width = 8, height = 6)
10. Exemplo completo: gráficos profissionais com qualidade de publicação
A seguir, apresentamos um exemplo de um fluxo de trabalho completo que reúne todos os tópicos abordados nesta aula.
▶ Exemplo: Vendas em 4 cidades — Gráficos com qualidade de publicação
# ============================================
# 4 City Sales: Publication-Quality Charts
# Features: Complete Customization from Default to Professional Level
# ============================================
library(ggplot2)
library(dplyr)
library(tidyr)
library(patchwork)
library(hrbrthemes)
# 1. Prepare data
sales_wide <- tibble(
city = c("Beijing", "Shanghai", "Guangzhou", "Shenzhen"),
Q1 = c(1000, 1500, 800, 1200),
Q2 = c(1200, 1800, 900, 1400),
Q3 = c(1100, 1700, 1000, 1300),
Q4 = c(1500, 2000, 1200, 1600)
)
sales_long <- sales_wide |>
pivot_longer(cols = -city, names_to = "quarter", values_to = "sales") |>
mutate(
total = sum(sales),
pct = round(sales / total * 100, 1)
)
# 2. Custom Themes
my_theme <- theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 16, hjust = 0,
margin = margin(b = 5)),
plot.subtitle = element_text(color = "gray40", size = 11,
margin = margin(b = 15)),
plot.caption = element_text(color = "gray50", size = 9,
hjust = 1, margin = margin(t = 10)),
axis.title = element_text(size = 11),
axis.text = element_text(size = 10, color = "gray30"),
panel.grid.major = element_line(color = "gray90", linewidth = 0.3),
panel.grid.minor = element_blank(),
legend.position = "top",
legend.title = element_text(size = 11),
legend.text = element_text(size = 10),
plot.background = element_rect(fill = "white", color = NA)
)
# 3. Plot 1: Line Trend (Professional Edition)
p1 <- ggplot(sales_long, aes(x = quarter, y = sales, color = city, group = city)) +
geom_line(linewidth = 1.2) +
geom_point(size = 3.5, fill = "white", shape = 21, stroke = 1.5) +
scale_color_brewer(palette = "Set1", name = "City") +
scale_y_continuous(labels = scales::comma, expand = expansion(mult = 0.1)) +
labs(
title = "2024 Annual Quarterly Sales Trends",
subtitle = "4 First-tier cities 4 Quarterly Sales Data",
caption = "Data Source: Sales System | Chart: Analyst Team",
x = NULL, y = "Sales (10,000 yuan)"
) +
my_theme
# 4. Plot 2: Bar Chart Comparison (Professional Edition)
total_sales <- sales_wide |>
mutate(total = Q1 + Q2 + Q3 + Q4) |>
arrange(desc(total)) |>
mutate(city = factor(city, levels = city))
p2 <- ggplot(total_sales, aes(x = city, y = total, fill = city)) +
geom_col(width = 0.7) +
geom_text(aes(label = scales::comma(total)), vjust = -0.5, size = 4) +
scale_fill_brewer(palette = "Set1", guide = "none") +
scale_y_continuous(labels = scales::comma,
expand = expansion(mult = c(0, 0.15))) +
labs(
title = "Annual Total Sales by City",
subtitle = "Sort by total sales in descending order",
x = NULL, y = "Total Sales (10,000 yuan)"
) +
my_theme
# 5. Plot 3: Stacked Columns (Professional Edition)
sales_long_ordered <- sales_long |>
left_join(total_sales |> select(city, total), by = "city") |>
mutate(city = factor(city, levels = total_sales$city))
p3 <- ggplot(sales_long_ordered, aes(x = city, y = sales, fill = quarter)) +
geom_col(position = "stack", width = 0.7) +
scale_fill_brewer(palette = "YlGnBu", name = "Quarter") +
labs(
title = "Quarterly Sales Breakdown by City",
subtitle = "Stacked bar chart showing quarterly contributions",
x = NULL, y = "Sales (10,000 yuan)"
) +
my_theme
# 6. Multi-Image Collage
combined <- (p1 / (p2 + p3)) +
plot_annotation(
title = "2024 4-City Comprehensive Sales Analysis",
theme = theme(plot.title = element_text(face = "bold", size = 18, hjust = 0.5))
)
print(combined)
# 7. Save Publication-Quality Images
ggsave("professional_report.png", combined,
width = 14, height = 12, dpi = 300)
ggsave("professional_report.pdf", combined,
width = 14, height = 12)
ggsave("professional_report.svg", combined,
width = 14, height = 12)
cat("\n=== Publishing-quality charts have been saved ===\n")
cat(" - professional_report.png (PNG 300dpi)\n")
cat(" - professional_report.pdf (PDF Vector)\n")
cat(" - professional_report.svg (SVG Vector)\n")
Resultado esperado: 3 conjuntos de gráficos com qualidade para publicação (gráfico de linhas + gráfico de barras + gráfico empilhado), incluindo títulos em chinês e inglês, esquemas de cores profissionais e legendas claras.
❓ Perguntas Frequentes
P: Qual é a diferença entre theme_minimal e theme_bw? R:
theme_minimalMinimal (fundo branco, grade cinza claro),theme_bwPreto e Branco (com bordas, grade bem definida). Use “minimal” para relatórios e “bw” ou “classic” para artigos.
P: Como faço para remover a grade secundária? R:
theme(panel.grid.minor = element_blank()). Isso deixa a imagem mais nítida.
P: Onde a legenda deve ser colocada? R: Depende da complexidade do gráfico. Para 1–2 variáveis, use
bottomoutop; para 4 ou mais variáveis, useright; e para gráficos de pizza incorporados em outros gráficos, usec(0.5, 0.5)para o posicionamento.
P: Qual é a diferença entre
scale_colorescale_fill? R:scale_colorcontrola a cor das linhas e dos pontos (cor do contorno), enquantoscale_fillcontrola a cor de preenchimento (para barras/áreas).geom_barusafillpor padrão,geom_lineusacolor.
P: 300 dpi ou 150 dpi? R: 300 dpi para impressão, 96–150 dpi para telas, e PDFs vetoriais não exigem dpi.
ggsaveO padrão é 300 dpi.
P: Como faço para alterar a fonte chinesa? R:
theme_minimal(base_family = "SimHei")(Windows) ou"PingFang SC"(macOS) ou"WenQuanYi Zen Hei"(Linux).
📖 Resumo
- O ggplot2 possui 8 temas integrados:
theme_graytheme_bwtheme_minimaltheme_classic, etc. theme()A árvore de elementos está dividida em 7 regiões: gráfico/eixo/legenda/painel/faixa/título- 4 tipos de funções de elementos:
element_textTexto /element_lineLinha /element_rectRetângulo /element_blankOculto - Ajustes finos no núcleo do tema:
plot.titleaxis.titlelegend.positionpanel.gridlabs()Definir todas as tags:titlesubtitlecaptionxycolorfill - Cor:
scale_color_brewer/scale_color_viridis_d/scale_color_manual - Pacotes temáticos especializados:
ggthemes(The Economist/The Wall Street Journal) /hrbrthemes(Negócios) ggsave("plot.png", dpi = 300)Padrão de impressão;ggsave("plot.pdf")Vetorial- Gráficos com qualidade de publicação = tema + cor + legendas + tamanho da fonte + ggsave em alta resolução
📝 Exercícios
-
Exercício básico: Use
mtcarspara criar um gráfico de dispersão dewtem função dempge utilize os quatro temastheme_minimal,theme_bw,theme_classicetheme_voidpara comparar as diferenças nos gráficos resultantes. Faça capturas de tela para comparação. -
Exercício básico: Crie um gráfico de barras e use
theme()para ajustá-lo: ① Coloque o título em negrito, tamanho 16; ② Oculte as linhas de grade secundárias; ③ Coloque a legenda na parte inferior; ④ Defina o título do eixo Y para ficar a 10 px de distância do eixo. -
Exercício básico: Desenhe a mesma imagem usando
scale_color_brewer(palette = "Set1")escale_color_brewer(palette = "Set2")e, em seguida, faça capturas de tela para comparar as diferenças de cor. -
Exercício avançado: Simule dados de vendas para quatro cidades e crie um gráfico completo, com qualidade de publicação, com as seguintes personalizações: ① Tema personalizado ② Rótulos “labs” completos ③ Esquema de cores profissional ④ Salvar em alta definição. Salve capturas de tela tanto do processo quanto dos resultados.
-
Desafio: Use o
ggthemesdotheme_economist()outheme_wsj()para fazer um desenho e compare as diferenças com otheme_minimal()padrão. Salve a imagem nos formatos PNG e PDF (use o dispositivo Cairo PDF para que o PDF suporte caracteres chineses).