Create a Gantt Chart Without Excel (feat. R & Lease Renewal)
It's not easy to keep track of the renewal and termination dates in the Residential Tenancy Act from text alone. You can use a Gantt chart in Excel, but there's an easier way. All you need to do is copy & paste the source code for the Gantt chart and run it.
In this post, we'll see how to use R to visualize a schedule of lease renewals and terminations. After signing a two-year lease on February 3, 2021, we'll use Implicit renewalsWe've also created a visual representation of when landlords and tenants should each give notice of non-renewal, so you can get a clearer picture of the important dates.

Create a Gantt Chart without Excel
Here's the lease schedule you want to visualize
- February 3, 2021: Contract starts
- February 2, 2023: End of contract
- August 3, 2022 - December 2, 2022: When landlords/tenants must give notice of non-renewal
- May 1, 2023: Tenant termination notice for cause after implied renewal
- August 1, 2023: End of contract and release of security deposit
If you sign a 2-year worldwide lease on February 3, 2021, your landlord will be able to legally terminate your lease for cause before the end date (February 2, 2023). 6 monthsOn or before August 3, 2022, the contract end date 2 monthsLandlords and tenants must give notice of non-renewal between December 2, 2022, and the end of the lease if they need to move for personal reasons. 2 monthsDecember 2, 2022, to give notice of non-renewal.
In this situation, assuming the implied renewal extended the worldwide lease for two more years, if the tenant gives notice to terminate on May 1, 2023, the landlord would be required to return the security deposit on August 1, 2023, three months after receiving the notice.
Now, let's visualize this complex schedule using R.
R Code to Create Gantt Charts without Excel Explained
First, install and load the required packages.
if (!require(ggplot2)) install.packages("ggplot2")
if (!require(dplyr)) install.packages("dplyr")
library(ggplot2)
library(dplyr)Create a data frame
Create a data frame for the data you want to visualize. Create a data frame with each time period and start and end dates.
df <- data.frame(
Task = c("Initial Contract Term", "Landlord Notice Period", "Tenant Notice Period",
"Renewal Contract Term", "3 months after notice"),
Start = as.Date(c("2021-02-03", "2022-08-03", "2022-08-03",
"2023-02-03", "2023-05-01"))),
End = as.Date(c("2023-02-02", "2022-12-02", "2022-12-02",
"2025-02-02", "2023-07-30"))),
Section = c("Initial Contract", "Notice of Non-Renewal", "Notice of Non-Renewal",
"Renewal Contract", "Contract Termination")
)Create a significant date data frame
Create a data frame of important dates. The data frame you created above is for framing purposes, and the dates in it are what you need to show dotted lines and date labels in your chart.
important_dates <- as.Date(c("2021-02-03", "2023-02-02", "2022-08-03", "2022-12-02",
"2023-01-02", "2023-02-03", "2025-02-02",
"2023-05-01", "2023-08-01")))
important_dates <- sort(important_dates)Improved date label repositioning function
Define a function to reposition the date labels so that they don't overlap each other. This is the tricky part, because if the date labels we want to display are too close together, they will overlap and be hard to see, so we implement a function that checks for dates that are within 7 days of each other and separates them up or down.
adjust_label_position <- function(dates) {
n <- length(dates)
positions <- rep(0, n)
last_position <- 0
for (i in 2:n) {
if (as.numeric(dates[i] - dates[i-1]) <= 7) { # Check for closest dates within 7 days
positions[i] <- (last_position + 1) %% 2 # alternate up and down based on previous position
last_position <- positions[i]
} else {
last_position <- 0
}
}
return(positions)
}Adjust the date label position
Use the function defined above to adjust the date label position.
label_positions <- adjust_label_position(important_dates)Create a date label data frame
Create a data frame with label positions.
date_labels <- data.frame(
x = important_dates,
y = length(df$Task) + 1,
label = format(important_dates, "%Y-%m-%d"),
position = label_positions
)Create and output plots (charts)
Generate a plot using ggplot2.
p <- ggplot() +
geom_segment(data = df, aes(x = Start, xend = End, y = Task, yend = Task, color = Section), size = 8) +
geom_vline(xintercept = important_dates, linetype = "dashed", color = "darkgray") +
geom_text(data = date_labels,
aes(x = x, y = y + ifelse(position == 0, -0.5, 0.5), label = label),
angle = 90, hjust = ifelse(date_labels$position == 0, 1, 0), vjust = 0.5, size = 3) +
scale_x_date(date_labels = "%Yyear %mmonth", date_breaks = "3 months") +
scale_y_discrete(limits = c(df$Task, "", "")) +
theme_minimal() +
labs(title = "Lease renewal and termination schedule (example)",
x = "date", y = "") +
theme(legend.position = "bottom",
plot.title = element_text(hjust = 0.5, size = 16),
axis.text.x = element_text(angle = 45, hjust = 1),
panel.grid.minor = element_blank())
print(p)Save as PNG format
Save the resulting plot as a PNG file.
ggsave("lease_renewal_process_with_alternating_labels.png", plot = p, width = 15, height = 10, dpi = 300)Full source code
Below is the full source code described above. Paste it in and run it to see the image you saw at the top of the post.
# 필요한 패키지 설치 및 로드
if (!require(ggplot2)) install.packages("ggplot2") # ggplot2 패키지가 없으면 설치
if (!require(dplyr)) install.packages("dplyr") # dplyr 패키지가 없으면 설치
library(ggplot2) # ggplot2 패키지 로드 (그래프 생성용)
library(dplyr) # dplyr 패키지 로드 (데이터 조작용)
# 데이터 프레임 생성
df <- data.frame(
Task = c("초기 계약 기간", "집주인 통지 가능 기간", "세입자 통지 가능 기간","갱신 계약 기간", "통보 후 3개월"), # 각 기간의 이름
Start = as.Date(c("2021-02-03", "2022-08-03", "2022-08-03","2023-02-03", "2023-05-01")), # 각 기간의 시작일
End = as.Date(c("2023-02-02", "2022-12-02", "2022-12-02","2025-02-02", "2023-07-30")), # 각 기간의 종료일
Section = c("초기 계약", "갱신 거절 통지", "갱신 거절 통지","갱신 계약", "계약 해지") # 각 기간의 분류
)
# 중요한 날짜 데이터 프레임 생성
important_dates <- as.Date(c("2021-02-03", "2023-02-02", "2022-08-03", "2022-12-02",
"2023-01-02", "2023-02-03", "2025-02-02",
"2023-05-01", "2023-08-01")) # 중요한 날짜들을 벡터로 정의
important_dates <- sort(important_dates) # 날짜를 오름차순으로 정렬
# 날짜 레이블 위치 조정 함수 개선
adjust_label_position <- function(dates) {
n <- length(dates)
positions <- rep(0, n) # 모든 위치를 0으로 초기화
last_position <- 0
for (i in 2:n) {
if (as.numeric(dates[i] - dates[i-1]) <= 7) { # 7일 이내의 근접한 날짜 확인
positions[i] <- (last_position + 1) %% 2 # 이전 위치에 따라 상하 교대 (0 또는 1)
last_position <- positions[i]
} else {
last_position <- 0
}
}
return(positions)
}
# 날짜 레이블 위치 조정
label_positions <- adjust_label_position(important_dates)
# 날짜 레이블 데이터 프레임 생성
date_labels <- data.frame(
x = important_dates, # x축 위치 (날짜)
y = length(df$Task) + 1, # y축 위치 (모든 Task 위에 위치)
label = format(important_dates, "%Y-%m-%d"), # 레이블 텍스트 (날짜 형식)
position = label_positions # 레이블의 상하 위치 (0 또는 1)
)
# 플롯 생성
p <- ggplot() +
geom_segment(data = df, aes(x = Start, xend = End, y = Task, yend = Task, color = Section), size = 8) +
# 각 Task에 대한 기간을 나타내는 선분. x: 시작일, xend: 종료일, y: Task 이름, color: Section으로 색상 구분
geom_vline(xintercept = important_dates, linetype = "dashed", color = "darkgray") +
# 중요한 날짜에 수직선 추가. linetype: 점선, color: 진한 회색
geom_text(data = date_labels,
aes(x = x, y = y + ifelse(position == 0, -0.5, 0.5), label = label),
angle = 90, hjust = ifelse(date_labels$position == 0, 1, 0), vjust = 0.5, size = 3) +
# 날짜 레이블 추가. x: 날짜 위치, y: Task 위 또는 아래, label: 날짜 텍스트
# angle: 90도 회전, hjust & vjust: 레이블 정렬, size: 글자 크기
scale_x_date(date_labels = "%Y년 %m월", date_breaks = "3 months") +
# x축 날짜 형식 설정. date_labels: 년월 표시 형식, date_breaks: 3개월 간격으로 눈금 표시
scale_y_discrete(limits = c(df$Task, "", "")) +
# y축 설정. limits: Task 이름들과 추가 여백 설정
theme_minimal() + # 최소한의 테마 적용
labs(title = "임대차 계약 갱신 및 해지 스케쥴 (예시)",
x = "날짜", y = "") + # 그래프 제목, x축 레이블 설정
theme(legend.position = "bottom", # 범례 위치를 아래로 설정
plot.title = element_text(hjust = 0.5, size = 16), # 제목 중앙 정렬 및 크기 설정
axis.text.x = element_text(angle = 45, hjust = 1), # x축 레이블 45도 회전
panel.grid.minor = element_blank()) # 작은 격자선 제거
# 플롯 출력
print(p)
# PNG 형식으로 저장
ggsave("lease_renewal_process_with_alternating_labels.png", plot = p, width = 15, height = 10, dpi = 300)
# 파일명, 플롯 객체, 너비, 높이, 해상도 설정Organize
In this post, we learned how to use R to visualize a lease renewal and termination schedule. Representing a complex contract schedule as a visualized schedule table makes it easy to see important dates at a glance.
First, I installed the necessary packages, prepared the data, and wrote a function to adjust the date labels so that they don't overlap. Then, I explained the process of using ggplot2 to create a visualization of the lease term and important dates, and saving it as a PNG file.
This visualization technique can help you not only with lease agreements, but also with a variety of scheduling and project planning. As you continue to explore different data visualization techniques, practice communicating the meaning of your data clearly. Additionally, we hope that you will develop the ability to make better decisions through visualized data.





