mirror of
https://github.com/kristoferssolo/LU-Data-Visualisation.git
synced 2025-10-21 20:10:40 +00:00
add comments
This commit is contained in:
parent
2d71178d42
commit
010cf92883
81
main.py
81
main.py
@ -20,27 +20,42 @@ logger.add(
|
|||||||
)
|
)
|
||||||
|
|
||||||
BASE_PATH = Path(__file__).parent
|
BASE_PATH = Path(__file__).parent
|
||||||
WIND_GUSTS_PATH = BASE_PATH.joinpath("data", "vejaAtrumsBrazmas.xlsx")
|
WIND_GUSTS_FILENAME = "vejaAtrumsBrazmas.xlsx"
|
||||||
WIND_SPEED_PATH = BASE_PATH.joinpath("data", "vejaAtrumsFaktiskais.xlsx")
|
WIND_SPEED_FILENAME = "vejaAtrumsFaktiskais.xlsx"
|
||||||
AIR_TEMP_PATH = BASE_PATH.joinpath("data", "gaisaTemperatura2022.xlsx")
|
AIR_TEMP_FILENAME = "gaisaTemperatura2022.xlsx"
|
||||||
PDF_PATH = BASE_PATH.joinpath("plots.pdf")
|
PDF_FILENAME = "plots.pdf"
|
||||||
|
|
||||||
BLUE = "#1f77b4"
|
BLUE = "#1f77b4"
|
||||||
ORANGE = "#ff7f0e"
|
ORANGE = "#ff7f0e"
|
||||||
BLACK = "#000000"
|
BLACK = "#000000"
|
||||||
|
|
||||||
|
|
||||||
@logger.catch
|
def read_data(filename: str) -> pd.DataFrame:
|
||||||
def read_data(path: Path) -> pd.DataFrame:
|
"""
|
||||||
|
Read data from Excel file and return a pandas DataFrame.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
FileNotFoundError: if the specified file is not found.
|
||||||
|
"""
|
||||||
|
possible_paths = [
|
||||||
|
BASE_PATH.joinpath(filename),
|
||||||
|
BASE_PATH.joinpath("data", filename),
|
||||||
|
]
|
||||||
|
|
||||||
|
for path in possible_paths:
|
||||||
|
if path.exists():
|
||||||
dataframe = pd.read_excel(path, parse_dates=["Datums"], index_col="Datums", date_format="%d.%m.%Y")
|
dataframe = pd.read_excel(path, parse_dates=["Datums"], index_col="Datums", date_format="%d.%m.%Y")
|
||||||
logger.info(f"Read data from {path}")
|
logger.info(f"Read data from {path}")
|
||||||
return dataframe
|
return dataframe
|
||||||
|
|
||||||
|
raise FileNotFoundError(f"Could not find {filename}")
|
||||||
|
|
||||||
|
|
||||||
@logger.catch
|
|
||||||
def create_bar_chart() -> plt.Figure:
|
def create_bar_chart() -> plt.Figure:
|
||||||
df_avg: pd.Series = read_data(WIND_SPEED_PATH).mean(axis=1)
|
"""Create a bar chart with average and maximum wind speed."""
|
||||||
df_max: pd.Series = read_data(WIND_GUSTS_PATH).max(axis=1) - df_avg
|
|
||||||
|
df_avg: pd.Series = read_data(WIND_SPEED_FILENAME).mean(axis=1)
|
||||||
|
df_max: pd.Series = read_data(WIND_GUSTS_FILENAME).max(axis=1) - df_avg
|
||||||
|
|
||||||
df_combined: pd.DataFrame = pd.concat(
|
df_combined: pd.DataFrame = pd.concat(
|
||||||
[df_avg, df_max],
|
[df_avg, df_max],
|
||||||
@ -49,7 +64,8 @@ def create_bar_chart() -> plt.Figure:
|
|||||||
|
|
||||||
fig, ax = plt.subplots(figsize=(12, 8))
|
fig, ax = plt.subplots(figsize=(12, 8))
|
||||||
|
|
||||||
df_combined.columns = ["Vidējais", "Maksimālais"]
|
df_combined.columns = ["Vidējais", "Maksimālais"] # Rename columns
|
||||||
|
|
||||||
df_combined.plot.bar(
|
df_combined.plot.bar(
|
||||||
stacked=True,
|
stacked=True,
|
||||||
figsize=(12, 8),
|
figsize=(12, 8),
|
||||||
@ -58,14 +74,17 @@ def create_bar_chart() -> plt.Figure:
|
|||||||
ax=ax,
|
ax=ax,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Format x-axis
|
||||||
date_format = df_combined.index.strftime("%d.%m.%Y")
|
date_format = df_combined.index.strftime("%d.%m.%Y")
|
||||||
ax.set_xticks(np.arange(len(date_format)))
|
ax.set_xticks(np.arange(len(date_format)))
|
||||||
ax.set_xticklabels(date_format, rotation=45)
|
ax.set_xticklabels(date_format, rotation=45)
|
||||||
|
ax.set_xlabel("Mērījumu Datums")
|
||||||
|
|
||||||
|
# Format y-axis
|
||||||
ax.set_yticks(np.arange(0, df_combined.max().max() + 2.5, 2.5))
|
ax.set_yticks(np.arange(0, df_combined.max().max() + 2.5, 2.5))
|
||||||
|
ax.set_ylabel("Vēja ātrums (m/s)")
|
||||||
|
|
||||||
ax.set_title("Vidējais un maksimālais vēja ātrums 2023. gada augustā")
|
ax.set_title("Vidējais un maksimālais vēja ātrums 2023. gada augustā")
|
||||||
ax.set_xlabel("Mērījumu Datums")
|
|
||||||
ax.set_ylabel("Vēja ātrums (m/s)")
|
|
||||||
|
|
||||||
logger.info("Created bar chart")
|
logger.info("Created bar chart")
|
||||||
|
|
||||||
@ -80,10 +99,12 @@ SEASONS: dict[int, str] = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@logger.catch
|
|
||||||
def create_box_plot() -> plt.Figure:
|
def create_box_plot() -> plt.Figure:
|
||||||
df: pd.DataFrame = read_data(AIR_TEMP_PATH)
|
"""Create a box plot showing the distribution of air temperature across seasons."""
|
||||||
|
|
||||||
|
df: pd.DataFrame = read_data(AIR_TEMP_FILENAME)
|
||||||
|
|
||||||
|
# Assign season to each row
|
||||||
df["Season"] = df.index.month % 12 // 3 + 1
|
df["Season"] = df.index.month % 12 // 3 + 1
|
||||||
df["Season"] = df["Season"].map(SEASONS)
|
df["Season"] = df["Season"].map(SEASONS)
|
||||||
|
|
||||||
@ -104,23 +125,36 @@ def create_box_plot() -> plt.Figure:
|
|||||||
widths=0.4,
|
widths=0.4,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Format x-axis
|
||||||
|
ax.set_xlabel("")
|
||||||
|
|
||||||
|
# Format y-axis
|
||||||
min_value: float = np.floor(df["Average"].min() / 5) * 5
|
min_value: float = np.floor(df["Average"].min() / 5) * 5
|
||||||
max_value: float = np.ceil(df["Average"].max() / 5) * 5
|
max_value: float = np.ceil(df["Average"].max() / 5) * 5
|
||||||
tick_step: int = 5
|
tick_step: int = 5
|
||||||
|
|
||||||
ax.set_yticks(np.arange(min_value, max_value, tick_step))
|
ax.set_yticks(np.arange(min_value, max_value, tick_step))
|
||||||
ax.set_title("Gaisa temperatūra Rīgā četros gadalaikos")
|
|
||||||
ax.set_ylabel("Gaisa temperatūra (Celsija grādos)")
|
ax.set_ylabel("Gaisa temperatūra (Celsija grādos)")
|
||||||
ax.set_xlabel("")
|
|
||||||
|
ax.set_title("Gaisa temperatūra Rīgā četros gadalaikos")
|
||||||
|
|
||||||
logger.info("Created box plot")
|
logger.info("Created box plot")
|
||||||
|
|
||||||
return fig
|
return fig
|
||||||
|
|
||||||
|
|
||||||
@logger.catch
|
def open_pdf(filename: str) -> None:
|
||||||
def open_pdf(pdf_path: Path) -> None:
|
"""
|
||||||
logger.info(f"Opening {pdf_path}")
|
Open a PDF file using the default system viewer.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
FileNotFoundError: if the specified file is not found.
|
||||||
|
"""
|
||||||
|
|
||||||
|
pdf_path = BASE_PATH.joinpath(filename)
|
||||||
|
if not pdf_path.exists():
|
||||||
|
raise FileNotFoundError(f"Could not find {pdf_path}")
|
||||||
|
|
||||||
|
logger.info(f"Opening {filename}")
|
||||||
|
|
||||||
system = platform.system().lower()
|
system = platform.system().lower()
|
||||||
if system == "linux":
|
if system == "linux":
|
||||||
@ -135,7 +169,10 @@ def open_pdf(pdf_path: Path) -> None:
|
|||||||
|
|
||||||
@logger.catch
|
@logger.catch
|
||||||
def main() -> None:
|
def main() -> None:
|
||||||
with PdfPages(PDF_PATH) as pdf:
|
"""Main function to generate and save plots to a PDF file, then open the PDF."""
|
||||||
|
|
||||||
|
# Generate and save plots to a PDF file
|
||||||
|
with PdfPages(PDF_FILENAME) as pdf:
|
||||||
fig1 = create_bar_chart()
|
fig1 = create_bar_chart()
|
||||||
pdf.savefig(fig1)
|
pdf.savefig(fig1)
|
||||||
plt.close(fig1)
|
plt.close(fig1)
|
||||||
@ -145,7 +182,7 @@ def main() -> None:
|
|||||||
plt.close(fig2)
|
plt.close(fig2)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
open_pdf(PDF_PATH)
|
open_pdf(PDF_FILENAME)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(e)
|
logger.error(e)
|
||||||
logger.warning("Something went wrong while opening the PDF. Please open it manually.")
|
logger.warning("Something went wrong while opening the PDF. Please open it manually.")
|
||||||
|
|||||||
@ -8,7 +8,6 @@ requires-python = ">=3.11"
|
|||||||
license = { text = "MIT" }
|
license = { text = "MIT" }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"openpyxl==3.1.2",
|
"openpyxl==3.1.2",
|
||||||
"attrs==23.1.0",
|
|
||||||
"loguru==0.7.2",
|
"loguru==0.7.2",
|
||||||
"matplotlib==3.8.2",
|
"matplotlib==3.8.2",
|
||||||
"pandas==2.1.4",
|
"pandas==2.1.4",
|
||||||
@ -18,9 +17,9 @@ dependencies = [
|
|||||||
check_untyped_defs = true
|
check_untyped_defs = true
|
||||||
disallow_any_generics = true
|
disallow_any_generics = true
|
||||||
ignore_missing_imports = true
|
ignore_missing_imports = true
|
||||||
# no_implicit_optional = true
|
no_implicit_optional = true
|
||||||
# no_implicit_reexport = true
|
no_implicit_reexport = true
|
||||||
# show_error_codes = true
|
show_error_codes = true
|
||||||
strict_equality = true
|
strict_equality = true
|
||||||
warn_redundant_casts = true
|
warn_redundant_casts = true
|
||||||
warn_return_any = true
|
warn_return_any = true
|
||||||
|
|||||||
@ -1,3 +1,2 @@
|
|||||||
mypy>=1.6.1
|
mypy>=1.6.1
|
||||||
pytest>=7.4.3
|
|
||||||
ruff>=0.1.4
|
ruff>=0.1.4
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user