Observable Plot… Tune ton graph !
  • Plot & mark
  • Channels & Colors
  • Documentation et exemples
data = [
    { "category": "A", "group":"alpha", "value": 3000 },
    { "category": "B", "group":"alpha", "value": 8000 },
    { "category": "C", "group":"beta", "value": 4500 },
    { "category": "D", "group":"beta", "value": 6000 },
    { "category": "E", "group":"gamma", "value": 2000 }
  ]
Plot = import("https://cdn.jsdelivr.net/npm/@observablehq/plot/+esm")

Plot.plot({
    title: title,
    subtitle: subtitle,
    caption: caption,

    marginTop: marginTop,
    marginRight: marginRight,
    marginBottom: marginBottom,
    marginLeft: marginLeft,

    height: height,
    width: width,

    style: {
        fontSize: fontSize
    },

    x: {
        label: Xlabel,
        grid: Xgrid,
        tickRotate: XtickRotate,
        inset: Xinset
    },
    y: {
        label: Ylabel,
        grid: Ygrid,
        domain:[0,maxDomain],
        ticks: nbTicks,
        tickFormat: d=> d.toLocaleString('fr-FR'), // permet d'enlever les , comme séparateurs de milliers
    },
    
    // utile si en fill on met une propriété
    //color: {legend: true},

    marks: [
        frame ? Plot.frame() : null, // si frame est true alors on fait un frame sinon on renvoie null = ne rien faire
        ruleX0 ? Plot.ruleX([0]) : null,
        ruleY0 ? Plot.ruleY([0]) : null,
        Plot.barY(data, {
            x: "category", 
            y: "value",
            fill: fill,
            fillOpacity: fillOpacity,
            stroke: stroke,
            strokeWidth: strokeWidth,
            strokeOpacity: strokeOpacity,
            insetRight : LRinset,
            insetLeft : LRinset,
            ry1: ry1,
            tip: {
                format: {          
                    y: d => Math.round(d).toLocaleString('fr-FR'),                  
                    }
            }
        })
    ],
})
data
md`[https://observablehq.com/plot/features/plots](https://observablehq.com/plot/features/plots)`
md`[https://observablehq.com/plot/features/marks](https://observablehq.com/plot/features/marks)`
md`*Exemple des principales possibilités avec un Plot.barY très simple*`
md`## Titres et légendes`
viewof title = Inputs.text({value:'Titre de mon graphe'})
viewof subtitle = Inputs.text({value:'Sous-titre de mon graphe'})
viewof caption = Inputs.text({value:'Figure 1. Légende de mon graph'})

md`## Marges`
viewof marginTop = Inputs.range([0,200], {label:"marginTop", value : 35, step : 1, width:50})
viewof marginRight = Inputs.range([0,200], {label:"marginRight", value : 5, step : 1, width:50})
viewof marginBottom = Inputs.range([0,200], {label:"marginBottom", value : 35, step : 1, width:50})
viewof marginLeft = Inputs.range([0,200], {label:"marginLeft", value : 45, step : 1, width:50})

md`## Taille graphe & police`
viewof height = Inputs.range([250,1000], {label:"height", value : 450, step : 10, width:50})
viewof width = Inputs.range([250,1000], {label:"width", value : 650, step : 10, width:50})
viewof fontSize = Inputs.range([8,20], {label:"fontSize", value : 12, step : 1, width:50})

md`## Abcisse, ordonnée, grilles et cadres`
viewof Xlabel = Inputs.text({value:'X label'})
viewof Xgrid = Inputs.toggle({label: "Xgrid", value: false})
viewof XtickRotate = Inputs.range([-90,90], {label:"X tickRotate", value : 0, step : 5, width:50})
viewof Xinset = Inputs.range([0,50], {label:"X inset", value : 0, step : 1, width:50})

viewof Ylabel = Inputs.text({value:'Y label'})
viewof Ygrid = Inputs.toggle({label: "Ygrid", value: true})
viewof maxDomain = Inputs.range([8000,12000], {label:"Y max", value : 8000, step : 1000, width:50})
viewof nbTicks = Inputs.range([0,12], {label:"Nombre de ticks Y", value : 8, step : 1, width:50})

viewof frame = Inputs.toggle({label: "frame", value: false})
viewof ruleX0 = Inputs.toggle({label: "ruleX0", value: false})
viewof ruleY0 = Inputs.toggle({label: "ruleY0", value: true})

md`## Cosmétique de la mark`
viewof fill = Inputs.color({label: "fill", value:"#6fcea9"})
viewof fillOpacity = Inputs.range([0,1], {label:"fillOpacity", value : 0.5, step : 0.1, width:50})
viewof stroke = Inputs.color({label: "stroke"})

viewof strokeWidth = Inputs.range([0,10], {label:"strokeWidth", value : 1, step : 1, width:50})
viewof strokeOpacity = Inputs.range([0,1], {label:"strokeOpacity", value : 1, step : 0.1, width:50})

viewof LRinset = Inputs.range([0,100], {label:"insetLeft et insetRight", value : 10, step : 1, width:50})
viewof ry1 = Inputs.range([0,10], {label:'round Corner x1-y1 and x2-y1, nécessite de mettre à jour Plot avec Plot = import("https://cdn.jsdelivr.net/npm/@observablehq/plot/+esm")', value : 5, step : 1, width:50})
Plot.plot({
    height:300,
    x: {type: "band"}, // plusieurs type de scales sont possibles time, band, point, à creuser...
    color: {
        legend: legend,
        type: "categorical",
        scheme: scheme
    },
    marks: [
        Plot.barY(data, {
            x: "category", 
            y: "value",
            fill: channelFill,
            //fillOpacity: "value",
            stroke: strokeFill,
            //strokeOpacity: "value",
            strokeWidth: 5,
            //opacity: "value",
        })
    ],
})
Plot.plot({
    height:300,
    r: {range: [0, radius]},    
    color: {
        legend: legend,
        type: "categorical",
        scheme: scheme
    },
    marks: [
        Plot.dotX(data, {
            x: "category", 
            r: "value",
            fill: channelFill,            
            stroke: strokeFill,
            strokeWidth: 1
        })
    ],
})
md`[https://observablehq.com/plot/features/scales](https://observablehq.com/plot/features/scales)`
md`*Exemple de quelques possibilités avec un Plot.barY et un Plot.dotX*`
md`## Légende`
viewof legend = Inputs.toggle({label: "legend", value: true})
viewof scheme = Inputs.select(["Observable10","accent", "category10", "dark2", "paired", "pastel1", "pastel2", "set1", "set2", "set3", "tableau10"],{label:"scheme",value:"Observable10"})

md`## Choix d'un channel`
viewof channelFill = Inputs.select(["category", "group"], {label:"fill (-> colonne pour couleur de remplissage)",value:"category"})
viewof strokeFill = Inputs.select(["category", "group"], {label:"stroke (-> colonne pour couleur de ligne)",value:"group"})

md`## Echelle`
md`*Selon le type de graphe, d'autres paramètres sont disponibles*`
viewof radius = Inputs.range([10,40], {label:'radius', value : 20, step : 1, width:50})
md`
## La documentation officielle :

[La documentation officielle sur https://observablehq.com/plot/getting-started](https://observablehq.com/plot/getting-started)

## La gallerie de graph

[Des dizaines d'exemples sur https://observablehq.com/\@observablehq/plot-gallery](https://observablehq.com/@observablehq/plot-gallery)

## Les **cheatsheets** :

[La feuille de triche en pdf à avoir sous la main...](https://github.com/observablehq/plot-cheatsheets/raw/main/plot-cheatsheets.pdf)

Et en notebooks : [Marks](https://observablehq.com/d/882059bb1761049d), [Scales](https://observablehq.com/d/93c789be8f819caf), [Layout](https://observablehq.com/d/b6ffda3b7612b969), [Transforms](https://observablehq.com/d/a742f171e7a58806), [Colors](https://observablehq.com/@clokman/plot-cheatsheets-colors)
`
// mystère ces pages redirigent vers le site de la doc alors qu'elles s'ouvrent via google... mystère j'ai pris les forks du coup
// Et en notebooks : [Marks](https://observablehq.com/@observablehq/plot-cheatsheets-marks), [Scales](https://observablehq.com/@observablehq/plot-cheatsheets-scales), [Layout](https://observablehq.com/@observablehq/plot-cheatsheets-layouts), [Transforms](https://observablehq.com/@observablehq/plot-cheatsheets-transforms), [Colors](https://observablehq.com/@observablehq/plot-cheatsheets-colors)