We can do it with calculate and bin transform, but it's a bit involving:

{
"$schema": "https://vega.github.io/schema/vega-lite/v3.json",
"data": {
"values": [
{"x": 0.01},
{"x": 0.1},
{"x": 1},
{"x": 1},
{"x": 1},
{"x": 1},
{"x": 10},
{"x": 10},
{"x": 100},
{"x": 500},
{"x": 800}
]
},
"transform": [{
"calculate": "log(datum.x)/log(10)", "as": "log_x"
}, {
"bin": {"step": 1},
"field": "log_x",
"as": "bin_log_x"
}, {
"calculate": "pow(10, datum.bin_log_x)", "as": "x1"
}, {
"calculate": "pow(10, datum.bin_log_x_end)", "as": "x2"
}],
"mark": "bar",
"encoding": {
"x": {
"field": "x1",
"type": "quantitative",
"scale": {"type": "log", "base": 10},
"axis": {"tickCount": 5}
},
"x2": {
"field": "x2"
},
"y": {
"aggregate": "count",
"type": "quantitative"
}
}
}
Ideally, we should be able to achieve the same thing with just:
{
"data": ...,
"mark": "bar",
"encoding": {
"x": {
"bin": {"log": 10}, // 10 = log-base
"field": "x1",
"type": "quantitative"
},
"y": {
"aggregate": "count",
"type": "quantitative"
}
}
}
Why not use the scale field?
e.g.
{
"data": ...,
"mark": "bar",
"encoding": {
"x": {
"bin": true,
"field": "x1",
"type": "quantitative",
"scale": {"type": "log"}
},
"y": {
"aggregate": "count",
"type": "quantitative"
}
}
}
Maybe, it's good in the sense there is only one place to put the keyword "log", but the trade-off is that scale type no longer just affect scale type but also affecting transforms before data goes through scale.
We should revisit this once we get to handle this issue.
Most helpful comment
Ideally, we should be able to achieve the same thing with just: