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
相关产品推荐
相关产品推荐

