---
title: "Production énergétique de source bois-énergie"
subtitle: "Production électrique et thermique, Vaud"
lang: fr
author: "DGE-DIREN"
date: last-modified # Renvoie automatiquement la date de dernière modification du .qmd
params: # ! `open_params_metadata_help()` pour des instructions de remplissage détaillées
fonction: 3 # Valeur numérique : 0=Non-défini/1=Description/2=Orientation/3=Pilotage
nature: 2 # Valeur numérique : 0=Non-défini/1=Actions/2=Effets/3=Impacts
idThematique: 08.02.05.40 # Identifiant selon nomenclature obsind theme/sous-theme/objet/id (p.ex. 08.03.01)
niveauPublication: 2 # Valeur numérique : 0=Non-défini/1=Interne/2=Public. Tout autre choix génère un avertissement
niveauDetail: Canton # Texte libre qui indique le niveau minimal d'agrégation disponible pour l'indicateur (canton, commune, région, installation, véhicule, etc.)
frequenceMAJ: Annuel # Texte libre, idéalement à choisir parmi les codes suivants : mensuel/semestriel/annuel/biannuel/mensuel/tous les x ans/non-défini
moisMAJ: 9 # Valeur numérique : 0=Non-défini/1=Janvier/2=Février, etc.
disponibleDepuis: 2015 # Valeur numérique Année (aaaa) (p.ex. 2000)
personneReference: Steve Ducommun # Prénom+Nom de la personne référente de l'indicateur
mailReference: stat.energie@vd.ch # E-mail ACV (générique ou nominal, se terminant par @vd.ch)
uuid: bee9b7bb-deb1-4089-9776-94c9211b94ad # !NE PAS MODIFIER! Identifiant unique généré automatiquement à la création de la fiche
uuidParent: null # Identifiant(s) unique(s) des indicateurs parents de l'indicateur actuel (format uuid avec séparateur '/' si plusieurs uuid)
uuidEnfant: null # Identifiant(s) unique(s) des indicateurs enfants de l'indicateur actuel (format uuid avec séparateur '/' si plusieurs uuid)
uuidConnexe: null # Identifiant(s) unique(s) des indicateurs connexes à l'indicateur actuel (format uuid avec séparateur '/' si plusieurs uuid)
majCatalogue: 1 # Valeur numérique : 0=Non/1=Oui pour mettre à jour les métadonnées dans le catalogue des indicateurs (connexion au disque partagé ObsInd requise)
format:
html:
other-links: # Copier la structure ci-dessous pour remplacer/ajouter d'autres liens sous la table des matières
- text: Infos statistiques énergie
href: 'https://www.vd.ch/environnement/energie/chiffres-cles-et-statistiques-energie-vaud/'
target: '_blank'
- text: Profil climatique communes
href: 'https://stat-climat-vd.ch/profil-climat/'
target: '_blank'
- text: Direction de l'énergie
href: 'https://www.vd.ch/djes/dge/dge-diren'
target: '_blank'
metadata-files: # Ne pas supprimer !
- assets/format-options.yml
editor_options:
chunk_output_type: console
---
<!-- Les métadonnées ci-dessus doivent être remplies pour chaque fiche. Lorsqu'un champ n'est disponible, il est possible d'écrire "" ou NULL -->
<!-- Aide au remplissage : `obsindVD::open_aide_remplissage_help()` (lancer la ligne de code dans la console) -->
```{r setup}
#| echo: false
#| warning: false
#| message: false
#| results: asis
# version: 1.2.2 (01.09.2026)
# -----------------------------------------------------------------------------
# Ne rien modifier dans ce bloc de code !
# Ce bloc doit être lancé pour charger les métadonnées dans l'environnement !
# -----------------------------------------------------------------------------
# update_model_setup_code() pour mettre à jour ce bloc avec la version du dernier modèle
# Chargement (ou installation) des librairies disponibles sur CRAN
if (!require("pacman")) install.packages("pacman")
pacman::p_load(tidyverse, readxl, glue, gt, DT, ggiraph, scales, ggtext)
# Chargement de la librairie obsindVD privée
# Pour l'installation : suivre les instructions dans le BitBucket : https://dsigit.etat-de-vaud.ch/outils/git/projects/DGE/repos/obsind/
# Si l'accès n'est pas autorisé, faire une demande à l'Observatoire des indicateurs
library(obsindVD)
# Par défaut : ouvrir l'aide obsindVD (supprimer cette ligne si superflu)
open_fiche_quarto_help()
# Vérifie, ajoute et insère des valeurs par défaut pour les métadonnées manquantes (en-tête YAML)
complete_metadata_params()
# Extraction + validation des métadonnées (en-tête YAML)
selected_metadata <- return_selected_metadata()
# Ajout de l'identifiant dans les en-têtes du document html
display_identifiant(value = selected_metadata[['Identifiant thématique']])
```
::: {.callout-tip .narrow icon="false" collapse="true"}
# Métadonnées de l'indicateur
```{r}
# --------------------------------------
# Présentation des métadonnées ----
# --------------------------------------
tidyr::tibble(
`Attribut` = names(selected_metadata),
`Valeur` = selected_metadata
) |>
gt_table_ind()
```
:::
```{r}
# Préciser quelle est l'année maximale recherchée (permet d'automatiser la recherche du bon dossier et fichier pour les données PRONOVO)
an_max <- 2025
```
```{r}
# ---------------------------------------------------------
# Tableau de synthèse ----
# ---------------------------------------------------------
# Pour de l'aide sur comment remplir ce tableau de synthèse lancer la commande suivante dans la console :
# obsindVD::open_tableau_synthese_help()
# Pour afficher l'aide spécifique à une fonction, ajouter '?' avant l'appel de la fonction :
# ?icon_up()
tableau_synthese <- list(
# Premier indicateur... attention à la structure !
list(
titre_indicateur = "Production **électrique** de source bois-énergie <b>[GWh]</b>",
valeur_2025 = 24.6,
obj_2030 = 70, # valeur numérique OU icônes de flèches
obj_2040 = NA,
obj_2050 = 100,
tendance_observée = icon_down(type = "trend", text = paste0("2019-", an_max)), # icon_up(), icon_flat(), icon_down()
tendance_évaluée = icon_sad() # icon_happy(), icon_meh(), icon_sad()
),
# Second indicateur... Répliquer la même structure autant de fois que d'indicateurs à afficher dans le tableau de synthèse
list(
titre_indicateur = "Production **thermique** de source bois-énergie <b>[GWh]</b>",
valeur_2025 = 567,
obj_2030 = 700, # valeur numérique OU icônes de flèches
obj_2040 = NA, # icon_up(type = "obj"), # On peut modifier 'Cible non chiffrée' en modifiant l'argument text = "" par exemple pour ne rien afficher
obj_2050 = 1000,
tendance_observée = icon_flat(type = "trend", text = paste0("2019-", an_max)), # text obligatoire pour type = 'trend'
tendance_évaluée = icon_meh() #(tooltip = "Exemple d'info-bulle personnalisé") # 'tooltip' modifie l'info-bulle par défaut
)
)
# Impression du tableau de synthèse
print_tableau_synthese(tableau_synthese) # Le résultat peut être customisé comme un objet {gt}
```
# Description {#sec-description}
Cet indicateur informe sur la quantité totale d'énergie électrique et thermique produite annuellement à partir de bois. Il traduit l’évolution de la production locale d’électricité et de chaleur à partir du bois-énergie, à savoir, le bois utilisé comme source d’énergie comparativement au bois utilisé à d’autres fins comme la construction.
# Cadre de référence {#sec-cadre-reference}
Les objectifs de la production d’énergie électrique et thermique à partir de bois-énergie sont définis dans la Conception cantonale de l’énergie ([CoCEn 2019](https://www.vd.ch/fileadmin/user_upload/themes/environnement/energie/fichiers_pdf/CoCEn_Pub_complete_20190816.pdf)). L’objectif est de plus que doubler la production actuelle jusqu’en 2030 pour atteindre une production d’électricité de 70 GWh<sub>él</sub> par an et d’atteindre une production annuelle thermique de 700 GWh<sub>th</sub>. Pour 2050, les objectifs sont respectivement de 100 GWh<sub>él</sub> et de 1000 GWh<sub>th</sub>.
# Graphique {#sec-graphique}
```{r}
# Lecture des données
#______________________________________________________________________
# 1 - Production thermique
# Le document data_brut.xlsx doit avoir été préparé et rempli avec les données
# setwd("P:/DIREN/11 POLITIQUE ENERG/11.08 Indicateurs et stat/1 Indicateurs DIREN/3-Fiches IND MET OBJ/INDicateur/Documents de travail - Quarto/Premières versions test/IND_08.01.03.02_Consommation_Batiments_Renouvelables")
data_brut_read <- readxl::read_excel(("./data/data_brut.xlsx"),
sheet = "data_final")
data_long <- data_brut_read |>
pivot_longer(
cols = -1, # toutes les colonnes sauf la 1ère
names_to = "ANNEE",
values_to = "VALEUR"
)
production_thermique <- data_long |>
# ne garder que THERMIQUE
filter(VARIABLES == "Thermique") |>
#enlever les objectifs des années
filter(!ANNEE %in% c(2030, 2050)) |>
mutate(ANNEE = as.numeric(ANNEE))
#______________________________________________________________________
# 2 - Production électrique
# Données de production électrique (lecture des données traitées (en kWh) sous meta_pronovo_résumé_2015-2022_2023-05-17.xlsx onglet qui se trouve sous: P:\DIREN\02 PILOTAGE DIREN\02.11 Bases de donnees\PRONOVO\04_extractions_traitees))
# Le document data_brut.xlsx doit avoir été préparé et rempli avec les données
# production_elec <- data_long |>
# # ne garder que ELEC ou THERMIQUE les totaux
# filter(VARIABLES == "Electrique") |>
# #enlever les objectifs des années
# filter(!ANNEE %in% c(2030, 2050)) |>
# # rename(GWH = VALEUR) |>
# mutate(ANNEE = as.numeric(ANNEE))
tryCatch(
expr = {
# Chemin du dossier
dossier <- glue("P:/DIREN/02 PILOTAGE DIREN/02.11 Bases de donnees/PRONOVO/04_extractions_traitees/Resultats_{an_max}")
# Lister tous les fichiers qui commencent par "meta_pronovo_résumé_2015-" et contiennent an_max (défini plus tôt)
fichiers <- list.files(
path = dossier,
pattern = glue("^meta_pronovo_résumé_2015-{an_max}.*\\.xlsx$"),
full.names = TRUE
)
# Extraire la date finale du nom de fichier et garder le plus récent
fichier_sel <- fichiers |>
tibble::enframe(name = NULL, value = "fichier") |>
mutate(
# extraire la date sous forme YYYY-MM-DD
date_fin = str_extract(fichier, "\\d{4}-\\d{2}-\\d{2}"),
date_fin = as.Date(date_fin)
) |>
arrange(desc(date_fin)) |> # trier par date décroissante
slice(1) |> # garder le premier (plus récent)
pull(fichier) # extraire le chemin complet
pronovo_detaille <- read_xlsx(fichier_sel,
sheet = "Détaillé")|>
janitor::clean_names(case="screaming_snake")
production_elec <- pronovo_detaille |>
filter(CATEGORIE_DIREN == "Bois-énergie") |>
# Convertir ANNEE en numérique pour pouvoir trier ou filtrer
mutate(ANNEE = as.integer(ANNEE),
VALEUR = PRODUCTION/1e6) |>
select(ANNEE,VALEUR)
# Export du file dans dossier data
write_delim(production_elec,"./data/production_bois_elec.csv", delim = ";")
},
error = function(e) stop(paste("Download failed: Il faut vérifier que le doc soit toujours ok", e$message)),
warning = function(w) stop(paste("Download failed: Il faut vérifier que le doc soit toujours ok", w$message))
)
production_elec <- read_delim("./data/production_bois_elec.csv", delim = ";")
# ---------------------------------------------------------
# 3 - Objectifs CoCEn
# créer data objectifs (uniquement objectifs des totaux)
objectifs_elec <- data_long |>
# # garder uniquement ELEC
filter(VARIABLES == "Electrique") |>
# garder uniquement les années d'objectifs
filter(ANNEE %in% c(2030, 2050)) |>
# enlever la colonne VARIABLES
select(-VARIABLES)|>
# rename(GWH = VALEUR)|>
mutate(ANNEE = as.numeric(ANNEE))
objectifs_thermique <- data_long |>
# # garder uniquement ELEC
filter(VARIABLES == "Thermique") |>
# garder uniquement les années d'objectifs
filter(ANNEE %in% c(2030, 2050)) |>
# enlever la colonne VARIABLES
select(-VARIABLES)|>
# rename(GWH = VALEUR)|>
mutate(ANNEE = as.numeric(ANNEE))
# ---------------------------------------------------------
# 4 - Population
# Variables sont : ANNEE et HABITANTS
tryCatch(
expr = {
read_delim("P:/DIREN/02 PILOTAGE DIREN/02.11 Bases de donnees/POPULATION/04_extractions_traitees/population.csv", delim=";") |>
write_delim("./data/population.csv", delim = ";")
},
error = function(e) message("Attention: la table population n'a pas pu être réactualisée avec les données brutes du P:/ ", e$message)
)
population <- read_delim("./data/population.csv", delim = ";") |>
filter(ANNEE >= 2015 & ANNEE <= an_max)
```
```{r }
#| label: fig-G1
##| fig-cap: "Production électrique de source bois-énergie, Vaud"
#| fig.width: 8
#| fig.asp: 0.6
#_______________________________________________________
# G1 - Production électrique de source bois-énergie, Vaud
#_______________________________________________________
# Prod_hab (obtenir la production par habitant)
production_temp <- production_elec |>
mutate(ANNEE = as.integer(as.numeric(ANNEE)))
prod_hab <- production_temp |>
left_join(population, by = "ANNEE") |>
mutate(KWH_HAB = (VALEUR*1e6) / HABITANTS) |>
select(ANNEE, KWH_HAB) |>
rename(VALEUR = KWH_HAB) |>
mutate(VARIABLE = "Production par habitant [kWh / hab]")
# Ajouter un trou pour séparer les consommations des objectifs
last_year <- max(production_temp$ANNEE, na.rm = TRUE)
gap1 <- last_year + 1 # entre dernière année et 2030
gap2 <- 2030 + 1 # entre 2030 et 2050
annees_hist <- sort(unique(production_temp$ANNEE))
annees_levels <- c(
annees_hist,
gap1,
2030,
gap2,
2050
)
# Ajout les trous à chaque dataset
add_missing_years <- function(df) {
tibble(ANNEE = annees_levels) |>
left_join(df, by = "ANNEE")
}
# production_temp <- add_missing_years(production_temp)
# # production_temp <- production_temp |>
# # filter(!is.na(VALEUR))
# prod_hab <- add_missing_years(prod_hab )
obj_graf <- add_missing_years(objectifs_elec) |>
filter(!is.na(VALEUR))
production_temp <- add_missing_years(production_temp |>
mutate(ANNEE = as.numeric(ANNEE)))
prod_hab <- add_missing_years(prod_hab |>
mutate(ANNEE = as.numeric(ANNEE)))
# Transformer ANNEE en facteur avec ordre
production_temp <- production_temp |>
mutate(ANNEE = factor(ANNEE, levels = annees_levels))
# |>
# mutate(VARIABLE = factor(VARIABLE, levels = c("INJECTION_GWH", "AUTOCONSOMMATION_GWH")))
prod_hab <- prod_hab |>
mutate(ANNEE = factor(ANNEE, levels = annees_levels))
obj_graf <- obj_graf |>
mutate(ANNEE = factor(ANNEE, levels = annees_levels)) |>
mutate(VARIABLE = "Objectifs CoCEn 2019")
# Coefficient
coef <- max(objectifs_elec$VALEUR, na.rm = TRUE) /
max(prod_hab$VALEUR, na.rm = TRUE)
# production_temp <- production_temp |>
# tidyr::complete(
# ANNEE,
# # VARIABLE = c("INJECTION_GWH", "AUTOCONSOMMATION_GWH"),
# fill = list(VALEUR = 0)
# )
production_temp <- production_temp |>
tidyr::complete(
# ANNEE = factor(annees_levels, levels = annees_levels),
ANNEE, fill = list(VALEUR = 0)) |>
# fill = list(VALEUR = 0, VARIABLE = "Total")
filter(ANNEE %in% annees_levels) |>
mutate(VARIABLE = "Total")
prod_hab <- prod_hab |>
tidyr::complete(ANNEE) |>
filter(ANNEE %in% annees_levels)
# production_temp <- production_temp |>
# mutate(VARIABLE = "Total")
g1_plot <- ggplot() +
# Bars (objectives )
geom_col_interactive(
data = obj_graf,
aes(x = ANNEE, y = VALEUR, fill = VARIABLE,
tooltip = paste("Production électrique de source bois-énergie", ANNEE, " : ", label_number(accuracy = 1, big.mark = "'")(VALEUR), "GWh"),
data_id = ANNEE),
width = 0.7,
position = position_nudge(x = -0.05),
color = NA
) +
# Barres empilées (autoconsommation et réseau)
geom_col_interactive(
data = production_temp,
aes(x = ANNEE, y = VALEUR, fill = VARIABLE,
color = VARIABLE,
tooltip = paste("Objectifs CoCEN", " ", ANNEE, " : ", label_number(accuracy = .1, big.mark = "'")(VALEUR), "GWh"),
data_id = ANNEE),
width = 0.7,
position = "stack",
color = NA
) +
# Line (per capita) – use factor + group = 1
geom_line(
data = prod_hab,
aes(x = ANNEE, y = VALEUR * coef, color = VARIABLE, group = 1),
linewidth = 1.2,
) +
geom_point_interactive(
data = prod_hab,
aes(
x = ANNEE,
y = VALEUR * coef,
color = VARIABLE,
tooltip = paste("Production électrique de source bois-énergie", " ", ANNEE, " : ", label_number(accuracy = .1, big.mark = "'")(VALEUR), "kWh/hab"),
data_id = ANNEE
),
size = 1.5
)+
scale_fill_manual(
values = c(
"Total" = "#f0d47a",
"Objectifs CoCEn 2019" = "grey80"
),
breaks = c("Total", "Objectifs CoCEn 2019"),
labels = c(
"Total" = "Production électrique totale [GWh]",
"Objectifs CoCEn 2019" = "Objectifs CoCEn 2019"
),
name = NULL,
na.translate = FALSE # afin d'éviter que NA apparaisse dans la légende
) +
guides(
fill = guide_legend(nrow = 1, byrow = TRUE),
color = guide_legend(nrow = 1, byrow = FALSE)
)+
scale_color_manual(
values = c(
"Total" = "#f0d47a",
"Objectifs CoCEn 2019" = "grey80",
"Production par habitant [kWh / hab]" = "#E6550D"
),
name = NULL,
na.translate = FALSE # afin d'éviter les NA dans la légende
)+
# Y axis with secondary axis
scale_y_continuous(
name = "Production électrique [GWh]",
labels = scales::label_number(big.mark = "'", decimal.mark = "."),
sec.axis = sec_axis(~ . / coef,
name = "Production par habitant [kWh / hab]",
labels = scales::label_number(big.mark = "'", decimal.mark = "."))
) +
scale_x_discrete(
drop = FALSE,
labels = function(x) {
num_x <- as.numeric(as.character(x))
ifelse(
num_x %in% c(gap1, gap2),
"", # cacher uniquement les gaps
as.character(num_x) # afficher toutes les autres années
)
}
)+
# Titles and caption
labs(
title = str_wrap("**Production électrique de source bois-énergie : total et par habitant, Vaud**", width = 73) |>
stringr::str_replace_all("\n", "<br>") ,
# Sous-titre sur deux lignes
subtitle = str_wrap("Electricité autoconsommée ou soutirée du réseau, Vaud", width = 73) |>
stringr::str_replace_all("\n", "<br>") ,
x = NULL,
caption = "Source: DGE-DIREN<br>Etat au 11.08.2026"
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_markdown(face = "bold", size = 12),
plot.subtitle = element_markdown(size = 10),
plot.caption = element_markdown(hjust = 0, size = 9, margin = margin(t = 5), face = "italic"), # !! MWR: rajout italic
plot.caption.position = "plot",
plot.margin = margin(10, 10, 30, 10),
legend.position = "bottom", # "top" "left" "right" "none"
legend.box = "vertical", #"horizontal"
legend.box.just = "left", # aligne les blocs à gauche
legend.justification = "left",
legend.text = element_text(size = 10),
legend.title = element_text(size = 12),
legend.spacing.y = unit(0.1, "cm"), # espace entre blocs
legend.margin = margin(t = 0, b = 0), # supprime marge globale
legend.box.spacing = unit(0.1, "cm"), # espace bloc-légende vs reste du plot
axis.text = element_text(size = 8),
axis.title = element_text(size = 10)
)
obsindVD::girafe_light(g1_plot,
# !!MWR : modification du comportement de surlignage : on ajoute de la transparence aux éléments non-survolés !
options = list(
opts_hover_inv(css = "opacity:0.5;"),
opts_hover(css = "opacity:1;"),
# Ajout du nom du PNG téléchargé + remplacement de 'download' par 'télécharger' (survol icône)
opts_toolbar(
position = "topright",
hidden = c("zoom", "selection"),
pngname = paste0(selected_metadata[['Identifiant thématique']], "_G1"),
tooltips = list(
saveaspng = "Télécharger"
)
)
)
)
ggsave(glue("./images/g1_Production_electrique_bois_2015-{an_max}.png"), width = 8, height = 6, dpi = 300)
prod_hab_elec <- prod_hab
```
```{r}
#| label: fig-G2
##| fig-cap: "Production thermique de source bois-énergie, Vaud"
#| fig.width: 8
#| fig.asp: 0.6
#_______________________________________________________
# G2 - Production thermique de source bois-énergie, Vaud
#_______________________________________________________
# Prod_hab (obtenir la production par habitant)
production_temp <- production_thermique |>
mutate(ANNEE = as.integer(as.numeric(ANNEE)))
prod_hab <- production_temp |>
left_join(population, by = "ANNEE") |>
mutate(KWH_HAB = (VALEUR*1e6) / HABITANTS) |>
select(ANNEE, KWH_HAB) |>
rename(VALEUR = KWH_HAB) |>
mutate(VARIABLE = "Production par habitant [kWh / hab]")
# Ajouter un trou pour séparer les consommations des objectifs
last_year <- max(production_temp$ANNEE, na.rm = TRUE)
gap1 <- last_year + 1 # entre dernière année et 2030
gap2 <- 2030 + 1 # entre 2030 et 2050
annees_hist <- sort(unique(production_temp$ANNEE))
annees_levels <- c(
annees_hist,
gap1,
2030,
gap2,
2050
)
# Ajout les trous à chaque dataset
add_missing_years <- function(df) {
tibble(ANNEE = annees_levels) |>
left_join(df, by = "ANNEE")
}
# production_temp <- add_missing_years(production_temp)
# # production_temp <- production_temp |>
# # filter(!is.na(VALEUR))
# prod_hab <- add_missing_years(prod_hab )
obj_graf <- add_missing_years(objectifs_thermique) |>
filter(!is.na(VALEUR))
production_temp <- add_missing_years(production_temp |>
mutate(ANNEE = as.numeric(ANNEE)))
prod_hab <- add_missing_years(prod_hab |>
mutate(ANNEE = as.numeric(ANNEE)))
# Transformer ANNEE en facteur avec ordre
production_temp <- production_temp |>
mutate(ANNEE = factor(ANNEE, levels = annees_levels))
# |>
# mutate(VARIABLE = factor(VARIABLE, levels = c("INJECTION_GWH", "AUTOCONSOMMATION_GWH")))
prod_hab <- prod_hab |>
mutate(ANNEE = factor(ANNEE, levels = annees_levels))
obj_graf <- obj_graf |>
mutate(ANNEE = factor(ANNEE, levels = annees_levels)) |>
mutate(VARIABLE = "Objectifs CoCEn 2019")
# Coefficient
coef <- max(objectifs_thermique$VALEUR, na.rm = TRUE) /
max(prod_hab$VALEUR, na.rm = TRUE)
# production_temp <- production_temp |>
# tidyr::complete(
# ANNEE,
# # VARIABLE = c("INJECTION_GWH", "AUTOCONSOMMATION_GWH"),
# fill = list(VALEUR = 0)
# )
production_temp <- production_temp |>
tidyr::complete(
# ANNEE = factor(annees_levels, levels = annees_levels),
ANNEE, fill = list(VALEUR = 0)) |>
# fill = list(VALEUR = 0, VARIABLE = "Total")
filter(ANNEE %in% annees_levels) |>
mutate(VARIABLE = "Total")
prod_hab <- prod_hab |>
tidyr::complete(ANNEE) |>
filter(ANNEE %in% annees_levels)
# production_temp <- production_temp |>
# mutate(VARIABLE = "Total")
g2_plot <- ggplot() +
# Bars (objectives )
geom_col_interactive(
data = obj_graf,
aes(x = ANNEE, y = VALEUR, fill = VARIABLE,
tooltip = paste("Objectifs CoCEn", " ", ANNEE, " : ", label_number(accuracy = 1, big.mark = "'")(VALEUR), "GWh"),
data_id = ANNEE),
width = 0.7,
position = position_nudge(x = -0.05),
color = NA
) +
# Barres empilées (autoconsommation et réseau)
geom_col_interactive(
data = production_temp,
aes(x = ANNEE, y = VALEUR, fill = VARIABLE, #était Serie
color = VARIABLE,
tooltip = paste("Production thermique de source bois-énergie", ANNEE, " : ", label_number(accuracy = 1, big.mark = "'")(VALEUR), "GWh"),
data_id = ANNEE),
width = 0.7,
position = "stack",
color = NA
) +
# Line (per capita) – use factor + group = 1
geom_line(
data = prod_hab,
aes(x = ANNEE, y = VALEUR * coef, color = VARIABLE, group = 1),
linewidth = 1.2,
) +
geom_point_interactive(
data = prod_hab,
aes(
x = ANNEE,
y = VALEUR * coef,
color = VARIABLE,
tooltip = paste(VARIABLE |> str_remove("\\[.*\\]"), " ", ANNEE, " : ", label_number(accuracy = 1, big.mark = "'")(VALEUR), "kWh/hab"),
data_id = ANNEE
),
size = 1.5
)+
scale_fill_manual(
values = c(
"Total" = "#f0d47a",
"Objectifs CoCEn 2019" = "grey80"
),
breaks = c("Total", "Objectifs CoCEn 2019"),
labels = c(
"Total" = "Production thermique totale [GWh]",
"Objectifs CoCEn 2019" = "Objectifs CoCEn 2019"
),
name = NULL,
na.translate = FALSE # afin d'éviter que NA apparaisse dans la légende
) +
guides(
fill = guide_legend(order = 2, nrow = 1, byrow = TRUE), # légendes sur 3 lignes d'un histogramme
color = guide_legend(order = 1, nrow = 1, byrow = FALSE) # légendes sur 1 lignes d'un graphique en ligne
)+
scale_color_manual(
values = c(
# "Total" = "#f0d47a",
# "Objectifs CoCEn 2019" = "grey80",
"Production par habitant [kWh / hab]" = "#E6550D"
),
breaks = c("Total", "Objectifs CoCEn 2019", "Production par habitant [kWh / hab]"),
name = NULL,
na.translate = FALSE # afin d'éviter les NA dans la légende
)+
# Y axis with secondary axis
scale_y_continuous(
name = "Production thermique [GWh]",
labels = scales::label_number(big.mark = "'", decimal.mark = "."),
sec.axis = sec_axis(~ . / coef,
name = "Production par habitant [kWh / hab]",
labels = scales::label_number(big.mark = "'", decimal.mark = "."))
) +
scale_x_discrete(
drop = FALSE,
labels = function(x) {
num_x <- as.numeric(as.character(x))
ifelse(
num_x %in% c(gap1, gap2),
"", # cacher uniquement les gaps
as.character(num_x) # afficher toutes les autres années
)
}
)+
# Titles and caption
labs(
title = str_wrap("**Production thermique de source bois-énergie : total et par habitant, Vaud**", width = 73) |>
stringr::str_replace_all("\n", "<br>") ,
# Sous-titre sur deux lignes
subtitle = " " ,
x = NULL,
caption = "Source: DGE-DIREN<br>Etat au 11.08.2026"
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_markdown(face = "bold", size = 12),
plot.subtitle = element_markdown(size = 10),
plot.caption = element_markdown(hjust = 0, size = 9, margin = margin(t = 5), face = "italic"), # !! MWR: rajout italic
plot.caption.position = "plot",
plot.margin = margin(10, 10, 30, 10),
legend.position = "bottom", # "top" "left" "right" "none"
legend.box = "vertical", #"horizontal"
legend.box.just = "left", # aligne les blocs à gauche
legend.justification = "left",
legend.text = element_text(size = 10),
legend.title = element_text(size = 12),
legend.spacing.y = unit(0.1, "cm"), # espace entre blocs
legend.margin = margin(t = 0, b = 0), # supprime marge globale
legend.box.spacing = unit(0.1, "cm"), # espace bloc-légende vs reste du plot
axis.text = element_text(size = 8),
axis.title = element_text(size = 10)
)
obsindVD::girafe_light(g2_plot,
# !!MWR : modification du comportement de surlignage : on ajoute de la transparence aux éléments non-survolés !
options = list(
opts_hover_inv(css = "opacity:0.5;"),
opts_hover(css = "opacity:1;"),
# Ajout du nom du PNG téléchargé + remplacement de 'download' par 'télécharger' (survol icône)
opts_toolbar(
position = "topright",
hidden = c("zoom", "selection"),
pngname = paste0(selected_metadata[['Identifiant thématique']], "_G2"),
tooltips = list(
saveaspng = "Télécharger"
)
)
)
)
ggsave(glue("./images/g2_Production_thermique_bois_2015-{an_max}.png"), width = 8, height = 6, dpi = 300)
prod_hab_thermique <- prod_hab
```
# Analyse {#sec-analyse}
<!-- Aide au remplissage : consulter la section correspondante avec `obsindVD::open_aide_remplissage_help()` -->
## Description statistique {#sec-analyse-description}
Les quantités d'électricité et de chaleur produites annuellement sur le territoire vaudois à partir de bois-énergie étaient relativement stables jusqu'en 2022 : près de 30 GWh<sub>él</sub> pour l’électricité et près de 600 GWh<sub>th</sub> pour la chaleur (voir @fig-G1). Après une hausse en 2023, des baisses sont observées depuis pour atteindre 24.6 GWh<sub>él</sub> pour l'électricité et 567 GWh<sub>th</sub> pour la chaleur (voir @tbl-T1).
L'objectif est d'atteindre une production électrique de 70 GWh<sub>él</sub> à moyen terme (2030) et de 100 GWh<sub>él</sub> à long terme (2050).
Pour la chaleur, l’objectif est d'atteindre une production de respectivement 700 et 1000 GWh<sub>th</sub> pour le moyen et le long terme.
## Interprétation {#sec-analyse-interpretation}
La tendance est qualifiée de mauvaise pour la production électrique: l'évolution observée ne va pas dans la direction souhaitée. Pour la production thermique, la tendance est qualifiée d'insuffisante: l'évolution observée va dans la direction souhaitée, mais progresse à un rythme insuffisant pour atteindre les objectifs fixés pour 2030 et 2050. Notons toutefois que ces valeurs cibles avaient été calculées pour la CoCEn 2019 avec une autre méthode de calcul que celle utilisée actuellement.
## Périmètre et limites {#sec-analyse-perimetre}
Le solde entre les importations et les exportations est supposé nul pour les catégories suivantes : bois de forêt, bois de compostière, bois de prairie et bois de sciage (bois transformé mécaniquement).
En revanche, pour le bois usagé, seule la part valorisée dans le canton de Vaud est prise en compte.
Le bois usagé valorisé dans le canton de Vaud ne tient pas compte de la masse de bois incinéré par TRIDEL, qui est comptabilisée dans les déchets incinérés.
Pour ce qui concerne la quantité annuelle de bois de prairie valorisée pour le bois énergie dans le canton de Vaud, seul le centre de la Direction générale de la mobilité et des routes (DGMR) de Bursins valorise du bois de prairie. Le bois de prairie récolté par les autres centres part en compostières.
# Tableaux {#sec-tableaux}
<!-- Aide au remplissage : consulter la section correspondante avec `obsindVD::open_aide_remplissage_help()` -->
```{r}
#| label: tbl-T1
##| tbl-cap: Production énergétique de source bois-énergie
# Changer nom de variable chez prod_hab
prod_hab_wide_elec <- prod_hab_elec |>
filter(!is.na(VALEUR)) |>
rename(KWH_HAB_ELEC = VALEUR) |>
mutate(ANNEE = as.integer(as.character(ANNEE)))
prod_hab_wide_thermique <- prod_hab_thermique |>
filter(!is.na(VALEUR)) |>
rename(KWH_HAB_THERMIQUE = VALEUR) |>
mutate(ANNEE = as.integer(as.character(ANNEE)))
prod_tot_wide_elec <- production_elec |>
rename(TOT_GWH_ELEC = VALEUR) |>
mutate(ANNEE = as.integer(as.character(ANNEE))) |>
filter(ANNEE <= an_max) |>
select(ANNEE, TOT_GWH_ELEC)
prod_tot_wide_thermique <- production_thermique |>
rename(TOT_GWH_THERMIQUE = VALEUR) |>
mutate(ANNEE = as.integer(as.character(ANNEE))) |>
filter(ANNEE <= an_max) |>
select(ANNEE, TOT_GWH_THERMIQUE)
obj_wide_elec <- objectifs_elec |>
rename(TOT_GWH_ELEC = VALEUR)
obj_wide_thermique <- objectifs_thermique |>
rename(TOT_GWH_THERMIQUE = VALEUR)
df_elec <- prod_tot_wide_elec |>
bind_rows(obj_wide_elec |> mutate(ANNEE = as.integer(ANNEE))) |>
filter(!is.na(TOT_GWH_ELEC)) |>
# left_join(prod_solaire_wide, by = "ANNEE") |>
left_join(prod_hab_wide_elec, by = "ANNEE") |>
select(ANNEE, TOT_GWH_ELEC, KWH_HAB_ELEC)
df_thermique <- prod_tot_wide_thermique |>
bind_rows(obj_wide_thermique |> mutate(ANNEE = as.integer(ANNEE))) |>
filter(!is.na(TOT_GWH_THERMIQUE)) |>
# left_join(prod_solaire_wide, by = "ANNEE") |>
left_join(prod_hab_wide_thermique, by = "ANNEE") |>
select(ANNEE, TOT_GWH_THERMIQUE, KWH_HAB_THERMIQUE)
df <- df_elec |>
left_join(df_thermique, by = "ANNEE") |>
select(ANNEE, TOT_GWH_ELEC, KWH_HAB_ELEC, TOT_GWH_THERMIQUE, KWH_HAB_THERMIQUE)
t1 <- df |>
mutate(across(everything(), \(col) na_if(col, y = 0))) |> # on change les 0 en NA comme ça sub_missing() ci-après transforme les 0 et les NA en "-" (par exemple)
gt() |>
tab_header(title = md("**Production électrique et thermique de source bois-énergie: total et par habitant, Vaud**")) |>
fmt_number(columns = c(TOT_GWH_ELEC, KWH_HAB_ELEC), sep_mark = "'", decimals = 1) |>
fmt_number(columns = c(TOT_GWH_THERMIQUE, KWH_HAB_THERMIQUE), sep_mark = "'", decimals = 0) |>
cols_label(
ANNEE = "Année",
TOT_GWH_ELEC = "Production électrique",
KWH_HAB_ELEC = "Production électrique par habitant",
TOT_GWH_THERMIQUE = "Production thermique",
KWH_HAB_THERMIQUE = "Production thermique par habitant"
) |>
cols_width(everything() ~ pct(100 / ncol(df))) |>
tab_style(style = cell_text(weight = "bold"),
locations = list(cells_body(columns = c("ANNEE", "TOT_GWH_ELEC", "TOT_GWH_THERMIQUE")),
cells_column_labels(columns = c("ANNEE", "TOT_GWH_ELEC", "TOT_GWH_THERMIQUE")))) |>
# spanners
tab_spanner(label = "Production électrique",
columns = c(TOT_GWH_ELEC, KWH_HAB_ELEC), level = 1) |>
tab_spanner(label = "Production thermique",
columns = c(TOT_GWH_THERMIQUE, KWH_HAB_THERMIQUE), level = 1) |>
tab_style(
style = cell_text(align = "center"),
locations = cells_column_labels()
) |>
tab_style(
style = cell_text(align = "left"),
locations = cells_column_labels(columns = ANNEE)
) |>
tab_style(
style = cell_text(align = "left"),
locations = list(cells_footnotes(), cells_source_notes())
) |>
tab_style(
style = cell_text(weight = "bold"),
locations = list(cells_column_spanners(), cells_column_labels())) |>
cols_align(align = "center", columns = -ANNEE) |>
cols_align(align = "left", columns = ANNEE) |>
cols_label_with(
columns = -c(ANNEE, KWH_HAB_ELEC, KWH_HAB_THERMIQUE),
fn = \(col) md(paste0("Total", "\n\n[GWh]"))
) |>
cols_label_with(
columns = c(KWH_HAB_ELEC, KWH_HAB_THERMIQUE),
fn = \(col) md(paste0("Par habitant", "\n\n[kWh / hab]"))
) |>
tab_style(style = cell_borders(sides = "all"),
locations = list(cells_column_labels(), cells_column_spanners())) |>
tab_style(style = cell_borders(sides = c("left", "right")),
locations = list(cells_body())) |>
tab_options(column_labels.border.bottom.color = "black") |>
fmt_missing(columns = everything(), missing_text = "") |>
tab_footnote(footnote = "Objectifs de la Conception cantonale de l'énergie (CoCEn 2019).",
locations = cells_body(columns = ANNEE, rows = ANNEE > year(Sys.Date())),
placement = "right") |>
tab_style(
style = cell_borders(sides = "top", style = "dashed", color = "lightgrey", weight = px(1)),
locations = cells_body(rows = ANNEE == min(objectifs_elec$ANNEE)) # applies to first row
) |>
opt_table_outline(style = "solid", width = px(2), color = "lightgrey") |>
tab_source_note(
source_note = md("*Sources : Pronovo / DGE-DIREN<br>Etat au 11.08.2026*")
)
t1
gtsave(t1, glue("./images/t1_Production_electrique_thermique_2015-{an_max}.html"))
```
# Méthode {#sec-methode}
La production électrique de source bois-énergie est obtenue par la quantité d'électricité injectée dans le réseau par les installations à bois-énergie, information transmise par Pronovo.
La production thermique de source bois-énergie est obtenue en additionnant la quantité totale d'énergie produite grâce aux différents assortiments de bois (bois, bois usagé (hors bois incinéré), bois de compostière, bois de prairie) multiplié par un rendement moyen de la production de chaleur, à laquelle on soustrait la production électrique.
Les détails des méthodes de calcul utilisées se trouvent dans une fiche méthode spécifique (voir @sec-ref-fiches).
# Comparaison {#sec-comparaison}
Aucune comparaison n'est possible, que ce soit avec d'autres cantons ou avec l'ensemble de la Suisse.
# Références {#sec-ref}
<!-- Aide au remplissage : consulter la section correspondante avec `obsindVD::open_aide_remplissage_help()` -->
## Fiches associées {#sec-ref-fiches}
**Fiches Méthode** :
* MET_08.02.02.02 : Méthode pour le calcul de la production d’électricité (*disponible sur demande*)
* MET_08.02.05.40 : Méthode pour le calcul de la production énergétique de source Bois-énergie (*disponible sur demande*)
**Fiches Indicateur** :
* [IND_08.02.02.01 : Production électrique de sources renouvelables et non renouvelables, Vaud](https://stat-climat-vd.ch/fiches-indicateurs/themes/energie/IND_08.02.02.01_Production_Electrique_Total.html)
* [IND_08.02.03.02 : Production thermique de sources renouvelables, Vaud](https://stat-climat-vd.ch/fiches-indicateurs/themes/energie/IND_08.02.03.02_Production_Thermique_Renouvelable.html)
## Autres références {#sec-ref-autres}
* [DGE-DIREN - Conception cantonale de l’énergie (CoCEn 2019)](https://www.vd.ch/fileadmin/user_upload/themes/environnement/energie/fichiers_pdf/CoCEn_Pub_complete_20190816.pdf)
# Glossaire {#sec-glossaire}
```{r}
# ---------------------------------------------------------
# Bloc pour lecture du file BRUT où se trouvent toutes les définition pour le glossaire et création du data.frame "definition" ----
# ---------------------------------------------------------
tryCatch(
expr = {readxl::read_excel("P:/DIREN/11 POLITIQUE ENERG/11.08 Indicateurs et stat/1 Indicateurs DIREN/3-Fiches IND MET OBJ/Liste Definitions.xlsx",
skip = 2) |>
janitor::clean_names(case="screaming_snake") |>
select(TERME, DEFINITION) |>
readr::write_csv2("./data/definitions.csv")
},
error = function(e) message("Attention: la table définition n'a pas pu être réactualisée avec les données brutes du P:/ ", e$message),
warning = function(w) message("Attention: la table définition n'a pas pu être réactualisée avec les données brutes du P:/ ", w$message)
)
```
```{r}
# ---------------------------------------------------------
# Bloc pour sélectionner les définitions à apparaître dans le glossaire ----
# ---------------------------------------------------------
# Lecture du file
def_tot <- readr::read_delim(file = "./data/definitions.csv",
delim = ";",
show_col_types = FALSE) |>
# Mettre les premières lettres de chaque définition en majuscule
dplyr::mutate(DEFINITION = stringr::str_replace(DEFINITION,"^\\p{L}",stringr::str_to_upper))
# Sélection des définitions
definitions <- def_tot |>
filter(TERME %in% c(
"Gigawattheure (GWh)"
))
# Ajouter Agents énergétiques
# Print de la table avec modification des columns
definitions |>
gt_table_ind() |>
gt::cols_label(TERME = "", DEFINITION ="Définition") |>
gt::tab_options(table.align = "left")
```
# Annexes {#sec-annexes .unnumbered}
<!-- Aide au remplissage : consulter la section correspondante avec `obsindVD::open_aide_remplissage_help()` -->