You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ggplot2中geom_line生成阶梯状线条,如何改为实线?

解决ggplot2中geom_line绘制阶梯状线条的问题

我使用ggplot2的geom_line函数生成的图形线条呈现阶梯状,而非预期的实线,请问如何修改才能绘制出正常的实线?

原始数据

0;0
0.000700;1.050
0.001750;1.100
0.003800;1.150
0.029110;1.200
0.130900;1.240
0.341428;1.303

原始代码

library(tidyverse)
library(reprex)

SAT <- read.delim("Curva_Tipica.txt", header = FALSE, encoding = "UTF-8")
SAT <- str_split(SAT[[1]],"; ") 
length_SAT <- length(SAT) + 1
curva_VxI <- tibble(
  .rows = length_SAT,
  I = 0,
  V = 0,
)

for (linha in 2:length_SAT) {
  curva_VxI$I[linha] <- as.double(SAT[[linha-1]][1])
  curva_VxI$V[linha] <- as.double(SAT[[linha-1]][2])
}

Xac <- (curva_VxI$V[length_SAT] - curva_VxI$V[length_SAT-1])/(curva_VxI$I[length_SAT] - curva_VxI$I[length_SAT-1])
Vj <- curva_VxI$V[length_SAT] - Xac*curva_VxI$I[length_SAT]

Xac_grafico <- tibble(
  x = c(0, 1),
  y = c(0, Xac)
)

Vj_grafico <- tibble(
  x = c(0),
  y = c(Vj)
)

theme_set(theme_bw())

ggplot() +
  geom_point(
    data = curva_VxI,
    aes(x = I, y = V),
    color = "orange",
    size = 2
  ) +
  geom_line(
    data = curva_VxI,
    aes(x = I, y = V),
    color = "orange",
    linewidth = 1
  ) +
  geom_point(
    data = Xac_grafico,
    aes(x = x, y = y),
    color = "blue",
  ) +
  geom_line(
    data = Xac_grafico,
    aes(x = x, y = y),
    color = "blue",
    linewidth = 1,
    linetype = "solid",
  ) +
  labs(
    y = "V (pu)",
    x = "I (pu)"
  ) +
  coord_cartesian(
    xlim = c(0, 1),
    ylim = c(0, 1.5),
    expand = FALSE,
    clip = "off"
  ) +
  scale_y_continuous(sec.axis = sec_axis(~.*1, "Xac (pu)")) +
  theme(
    axis.title.x = element_text(margin = margin(t = 10), size = 12, face = "bold"),
    axis.title.y = element_text(margin = margin(r = 10), size = 12, face = "bold"),
    axis.text.x = element_text(size = 10),
    axis.text.y = element_text(size = 10),
    legend.position = "top",
    plot.margin = margin(t = 1, r = 1, b = 0.5, l = 0.5, unit = "cm")
  )

问题原因

原始代码中手动创建了包含(0,0)的curva_VxI数据框,又将原始数据的第一行(0,0)再次添加进去,导致数据框里存在两个完全相同的原点。后续数据点的x值极小(远小于x轴范围0-1),但y值大幅上升,在视觉上就呈现出了阶梯状的线条。

解决方案

简化数据读取和处理逻辑,直接读取原始数据并转换为数值型,避免重复添加原点:

修正后的完整代码

library(tidyverse)
library(reprex)

# 直接读取分号分隔的数据,无需手动拆分字符串
SAT <- read.delim("Curva_Tipica.txt", header = FALSE, sep = ";", encoding = "UTF-8")
# 重命名列并转换为数值型
curva_VxI <- SAT %>% 
  rename(I = V1, V = V2) %>% 
  mutate(across(c(I, V), as.double))

Xac <- (curva_VxI$V[nrow(curva_VxI)] - curva_VxI$V[nrow(curva_VxI)-1])/(curva_VxI$I[nrow(curva_VxI)] - curva_VxI$I[nrow(curva_VxI)-1])
Vj <- curva_VxI$V[nrow(curva_VxI)] - Xac*curva_VxI$I[nrow(curva_VxI)]

Xac_grafico <- tibble(
  x = c(0, 1),
  y = c(0, Xac)
)

Vj_grafico <- tibble(
  x = c(0),
  y = c(Vj)
)

theme_set(theme_bw())

ggplot() +
  geom_point(
    data = curva_VxI,
    aes(x = I, y = V),
    color = "orange",
    size = 2
  ) +
  geom_line(
    data = curva_VxI,
    aes(x = I, y = V),
    color = "orange",
    linewidth = 1
  ) +
  geom_point(
    data = Xac_grafico,
    aes(x = x, y = y),
    color = "blue",
  ) +
  geom_line(
    data = Xac_grafico,
    aes(x = x, y = y),
    color = "blue",
    linewidth = 1,
    linetype = "solid",
  ) +
  labs(
    y = "V (pu)",
    x = "I (pu)"
  ) +
  coord_cartesian(
    xlim = c(0, 1),
    ylim = c(0, 1.5),
    expand = FALSE,
    clip = "off"
  ) +
  scale_y_continuous(sec.axis = sec_axis(~.*1, "Xac (pu)")) +
  theme(
    axis.title.x = element_text(margin = margin(t = 10), size = 12, face = "bold"),
    axis.title.y = element_text(margin = margin(r = 10), size = 12, face = "bold"),
    axis.text.x = element_text(size = 10),
    axis.text.y = element_text(size = 10),
    legend.position = "top",
    plot.margin = margin(t = 1, r = 1, b = 0.5, l = 0.5, unit = "cm")
  )

修改后,geom_line会按正确的顺序连接所有数据点,线条将呈现为预期的实线,不会再出现阶梯状效果。

内容的提问来源于stack exchange,提问作者Gabryel Mota

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 19:55:12