data_DPL_scenarios_t =transpose (data_DPL_scenarios)// mettre à jour librairie plot pour faire des round cornersPlot =import("https://cdn.jsdelivr.net/npm/@observablehq/plot/+esm")viewof myTerritoire = Inputs.select(data_DPL_scenarios_t, {format: d => d.zone_DPL,label:"",width:400})territoire = data_DPL_scenarios_t.filter(d => d.zone_DPL== myTerritoire.zone_DPL)
Le territoire de aurait un besoin de logements par an pour le scénario central.
Plot.plot({marginLeft:100,marginRight:100,marginTop:50,height:300,width:450,style: {fontSize:12, },y: {tickFormat: d => d.toLocaleString('fr-FR'),grid:true,label:"Nb de logements / an"},x: {label:"",inset:70},color: {legend:true,domain: ["lgts commencés 2015-2019","lgts commencés 2020-2023 (Sitadel)"],// les catégories de fillrange: ["orange","#16fa53"] // les couleurs que tu choisis },subtitle:"Estimation de la demande potentielle en logements à horizon 2035 (moyenne annuelle)",marks: [ Plot.barY(territoire, {x:"Libellé zonage",y1:"Tendanciel BAS",y2:"Tendanciel HAUT",fill:"steelblue",r:5 }), Plot.dot(territoire, {x:"Libellé zonage",y:"Tendanciel BAS",fill:"steelblue",symbol:"diamond",r:10,tip:false }), Plot.dot(territoire, {x:"Libellé zonage",y:"Tendanciel HAUT",fill:"steelblue",symbol:"diamond",r:10,tip:false }), Plot.dot(territoire, {x:"Libellé zonage",y:"Tendanciel CENTRAL",fill:"black",symbol:"star",r:5,tip:false }), Plot.ruleY([0]), Plot.tip( [`Scénario central à ${myTerritoire["Tendanciel CENTRAL"]} logt/an`], {x:"Libellé zonage",y: myTerritoire["Tendanciel CENTRAL"],dy:3,anchor:"left"} ), Plot.tip( [`Scénario haut à ${myTerritoire["Tendanciel HAUT"]} logt/an`], {x:"Libellé zonage",y: myTerritoire["Tendanciel HAUT"],dy:3,anchor:"left"} ), Plot.tip( [`Scénario bas à ${myTerritoire["Tendanciel BAS"]} logt/an`], {x:"Libellé zonage",y: myTerritoire["Tendanciel BAS"],dy:3,anchor:"left"} ), Plot.tickY(logt_comm_periode, {x:"Libellé zonage",y:"Logts ordinaires commencés /an",stroke:"periode",strokeWidth:2,fill:"periode",tip:true }) ]})
Code
data_long_central_ojs =transpose (data_long_central)territoire2 = data_long_central_ojs.filter(d => d["Libellé zonage"] == myTerritoire["Libellé zonage"])// territoire2colorPalette = { return {"Ménage par an – effet nouvelle population":"#83caff",// Bleu"Ménage par an – effet déformation pyramide des âges":"#9999ff",// Violet"Ménage par an – effet évolution des modes de cohabitation":"#198a8a",// Cyan"Renouvellement par an":"#c5000b",// Rouge"Vacance par an":"#ffd320",// Jaune"Résidences Secondaires et Logts Occasion. par an":"#81d41a"// Vert}};
Code
Plot.plot({marginLeft:100,marginRight:200,height:300,width:400,style: {fontSize:12, },x: {label:""},y: {grid:true,label:"Nb de logts / an",tickFormat: y => y.toLocaleString('fr-FR') },color: {legend:true,domain:Object.keys(colorPalette),range:Object.values(colorPalette)},subtitle:"Origine de la demande potentielle (scénario central)",marks: [ Plot.barY(territoire2.filter(d => d.effet!="Moyenne annuelle Demande Potentielle logements"), {x:"Libellé zonage",y:"valeur",fill:"effet",tip:true }), Plot.ruleY([0]),// Cercle pour le fond de texte Plot.dotY(territoire2.filter(d => d.effet=="Moyenne annuelle Demande Potentielle logements"), {x:"Libellé zonage",y:"valeur",fill:"white",stroke:"black",r:20 }), Plot.text(territoire2.filter(d => d.effet=="Moyenne annuelle Demande Potentielle logements"), {x:"Libellé zonage",y:"valeur",//text: "valeur",text: d =>Math.round(d.valeur).toLocaleString('fr-FR'),fontSize:11,textAnchor:"middle" }) ]})
Code
data_long_age_2018_t =transpose (data_long_age_2018)data_long_age_2035_t =transpose (data_long_age_2035)// On ajoute la propriété année à 2018temp_2018 = data_long_age_2018_t.map(objet => ({...objet,annee:"2018"// en texte parce que c'est pas des choses que je veux additioner ou mettre en continu}));// On ajoute la propriété année à 2018temp_2035 = data_long_age_2035_t.map(objet => ({...objet,annee:"2035"}));// on fusionne les 2 tableauxdata_long_age_2018_2035_t = [...temp_2018,...temp_2035]// pour mémoire, on récupère du texte dans valeur, on les retransforme en nombre du coup...territoire3 = data_long_age_2018_2035_t.filter(d => d["Libellé zonage"] == myTerritoire["Libellé zonage"])
Code
Plot.plot({label:null,marginLeft:70,width:500,height:160,y: {label:"nb ménages",grid:true,tickFormat: y => y.toLocaleString('fr-FR') },x: { domain: ["< 35 ans","35-49 ans","50-64 ans","65-79 ans","> 80 ans"]},color: {legend:true,domain: ["2018","2035"],// les catégories de fillrange: ["steelblue","#b00465"] // les couleurs que tu choisis },subtitle:"Age de la personne de référence des ménages",marks: [ Plot.lineY(territoire3, {x:"tranche_age",y: d =>Number(d.valeur.replace(/\s/g,"")),stroke:"annee" }), Plot.dot(territoire3, {x:"tranche_age",y: d =>Number(d.valeur.replace(/\s/g,"")),tip:true,fill:"annee" }), Plot.ruleY([0]), Plot.axisX({y:0}) ]})
colorPalette2 = { return {"Couple avec ou sans enfant":"#81d41a",// vert"Personne seule":"#800080",// Violet"Famille monoparentale":"#729fcf",// bleu"Personne hors famille":"#8d281e"// marron}};Plot.plot({label:null,marginLeft:150,marginBottom:50,width:600,height:150,x: {label:"nb ménages /an sur la période 2018-2035",labelAnchor:"center",x: (d) => d.valeur.toLocaleString('fr-FR'),tickFormat: y => y.toLocaleString('fr-FR'),grid:true },y: { domain: ["Personne hors famille","Famille monoparentale","Personne seule","Couple avec ou sans enfant"],axis:"left" },color: {legend:true,domain:Object.keys(colorPalette2),range:Object.values(colorPalette2)},subtitle:"Variation annuelle du nombre de ménages selon leur type",marks: [ Plot.barX(territoire6, {x:"valeur",y:"mode_cohab",r:3,channels: {nb_menages: d => d.valeur.toLocaleString('fr-FR')},tip: { format: {x:false,y:true,fill:false }},fill:"mode_cohab" }), Plot.ruleX([0]) ]})
import { aq, op } from'@uwdata/arquero'// https://observablehq.com/@uwdata/an-illustrated-guide-to-arquero-verbs// 1ère étape on met la donnée au format arquero avec aq.fromdt_territoire7 = aq.from(territoire7);// 2ème étape, on chaîne les opérations et on ajuste selon les résultats// je te met un exemple pour arrondir mais là tu peux tout faire : renommer, réordonner, changer l'unité, pivoter etc...// cf doc du lien au dessus, c'est fold pour pivoter à la vertical, tes données seront jamais lisible à l'horizontaledt_territoire7_pivot = dt_territoire7.derive({"Nombre de ménages au 1er janvier 2018": aq.escape(d=> (Math.round(d["Nombre de ménages au 1er janvier 2018"])).toLocaleString('fr-FR') ),"Nombre de ménages au 1er janvier 2035 – scénario BAS": aq.escape(d=> (Math.round(d["Nombre de ménages au 1er janvier 2035 – scénario BAS"])).toLocaleString('fr-FR') ),"Nombre de ménages au 1er janvier 2035 – scénario CENTRAL": aq.escape(d=> (Math.round(d["Nombre de ménages au 1er janvier 2035 – scénario CENTRAL"])).toLocaleString('fr-FR') ),"Nombre de ménages au 1er janvier 2035 – scénario HAUT": aq.escape(d=> (Math.round(d["Nombre de ménages au 1er janvier 2035 – scénario HAUT"])).toLocaleString('fr-FR') ),"Evol. Ménages 2018-2035 – scénario BAS": aq.escape(d=> (Math.round(d["Evol. Ménages 2018-2035 – scénario BAS"])).toLocaleString('fr-FR') ),"Evol. Ménages 2018-2035 – scénario CENTRAL": aq.escape(d=> (Math.round(d["Evol. Ménages 2018-2035 – scénario CENTRAL"])).toLocaleString('fr-FR') ),"Evol. Ménages 2018-2035 – scénario HAUT": aq.escape(d=> (Math.round(d["Evol. Ménages 2018-2035 – scénario HAUT"])).toLocaleString('fr-FR') ),"Taux accroissement annuel des ménages – scénario BAS": aq.escape(d=> (Math.round(d["Taux accroissement annuel des ménages – scénario BAS"]*10000)/100).toLocaleString('fr-FR') +"%"),"Taux accroissement annuel des ménages – scénario CENTRAL": aq.escape(d=> (Math.round(d["Taux accroissement annuel des ménages – scénario CENTRAL"]*10000)/100).toLocaleString('fr-FR') +"%"),"Taux accroissement annuel des ménages – scénario HAUT": aq.escape(d=> (Math.round(d["Taux accroissement annuel des ménages – scénario HAUT"]*10000)/100).toLocaleString('fr-FR') +"%"),"Taux de renouvellement annuel retenu – scénario BAS": aq.escape(d=> (Math.round(d["Taux de renouvellement annuel retenu – scénario BAS"]*100000)/1000).toLocaleString('fr-FR') +"%"),"Taux de renouvellement annuel retenu – scénario CENTRAL": aq.escape(d=> (d["Taux de renouvellement annuel retenu – scénario CENTRAL"]*100).toLocaleString('fr-FR', { minimumFractionDigits:3,maximumFractionDigits:3 }) +"%"),"Taux de renouvellement annuel retenu – scénario HAUT": aq.escape(d=> (d["Taux de renouvellement annuel retenu – scénario HAUT"]*100).toLocaleString('fr-FR', { minimumFractionDigits:3,maximumFractionDigits:3 }) +"%"),"Besoins annuels liés au renouvellement du parc 2021-2035 – scénario BAS": aq.escape(d=> (Math.round(d["Besoins annuels liés au renouvellement du parc 2021-2035 – scénario BAS"])).toLocaleString('fr-FR')),"Besoins annuels liés au renouvellement du parc 2021-2035 – scénario CENTRAL": aq.escape(d=> (Math.round(d["Besoins annuels liés au renouvellement du parc 2021-2035 – scénario CENTRAL"])).toLocaleString('fr-FR')),"Besoins annuels liés au renouvellement du parc 2021-2035 – scénario HAUT": aq.escape(d=> (Math.round(d["Besoins annuels liés au renouvellement du parc 2021-2035 – scénario HAUT"])).toLocaleString('fr-FR')),"Taux LV au 1er janvier 2035 – scénario BAS": aq.escape(d=> (Math.round(d["Taux LV au 1er janvier 2035 – scénario BAS"]*10000)/100).toLocaleString('fr-FR') +"%"),"Taux LV au 1er janvier 2035 – scénario CENTRAL": aq.escape(d=> (Math.round(d["Taux LV au 1er janvier 2035 – scénario CENTRAL"]*10000)/100).toLocaleString('fr-FR') +"%"),"Taux LV au 1er janvier 2035 – scénario HAUT": aq.escape(d=> (Math.round(d["Taux LV au 1er janvier 2035 – scénario HAUT"]*10000)/100).toLocaleString('fr-FR') +"%"),"Nombre de logements vacants projeté au 1er janvier 2035 – scénario BAS": aq.escape(d=> (Math.round(d["Nombre de logements vacants projeté au 1er janvier 2035 – scénario BAS"])).toLocaleString('fr-FR')),"Nombre de logements vacants projeté au 1er janvier 2035 – scénario CENTRAL": aq.escape(d=> (Math.round(d["Nombre de logements vacants projeté au 1er janvier 2035 – scénario CENTRAL"])).toLocaleString('fr-FR')),"Nombre de logements vacants projeté au 1er janvier 2035 – scénario HAUT": aq.escape(d=> (Math.round(d["Nombre de logements vacants projeté au 1er janvier 2035 – scénario HAUT"])).toLocaleString('fr-FR')),"Taux de RS/LO visé au 1er janvier 2035 – scénario BAS": aq.escape(d=> (Math.round(d["Taux de RS/LO visé au 1er janvier 2035 – scénario BAS"]*10000)/100).toLocaleString('fr-FR') +"%"),"Taux de RS/LO visé au 1er janvier 2035 – scénario CENTRAL": aq.escape(d=> (Math.round(d["Taux de RS/LO visé au 1er janvier 2035 – scénario CENTRAL"]*10000)/100).toLocaleString('fr-FR') +"%"),"Taux de RS/LO visé au 1er janvier 2035 – scénario HAUT": aq.escape(d=> (Math.round(d["Taux de RS/LO visé au 1er janvier 2035 – scénario HAUT"]*10000)/100).toLocaleString('fr-FR') +"%"),"Nombre de RS/LO projeté au 1er janvier 2035 – scénario BAS": aq.escape(d=> (Math.round(d["Nombre de RS/LO projeté au 1er janvier 2035 – scénario BAS"])).toLocaleString('fr-FR')),"Nombre de RS/LO projeté au 1er janvier 2035 – scénario CENTRAL": aq.escape(d=> (Math.round(d["Nombre de RS/LO projeté au 1er janvier 2035 – scénario CENTRAL"])).toLocaleString('fr-FR')),"Nombre de RS/LO projeté au 1er janvier 2035 – scénario HAUT": aq.escape(d=> (Math.round(d["Nombre de RS/LO projeté au 1er janvier 2035 – scénario HAUT"])).toLocaleString('fr-FR')) }).fold(aq.all()) // ça c'est le pivot.rename({'key':'Indicateur','value':'Valeur' }) // et là on renomme key et value (noms automatiques) comme on veut.filter(d => d["Valeur"])
Code
// cf option dans l'exemple :// https://observablehq.com/@observablehq/input-tableauInputs.table(dt_territoire7_pivot,{width: {"Indicateur":500// pour pas avoir une trop petite première colonne },rows:50,// pour éviter l'ascenceur dans le tableau, faudrait compter pour de vrai...})
Graphes pour s’amuser
Code
data_DPL_scatterplot_t =transpose (data_DPL_scatterplot)viewof indicateur1 = Inputs.select(Object.keys(data_DPL_scatterplot_t[0]).slice(1), {label:"choix de l'indicateur en abscisse",width:500})viewof indicateur2 = Inputs.select(Object.keys(data_DPL_scatterplot_t[0]).slice(1), {label:"choix de l'indicateur en ordonnée",width:500})