如何在 D3.js 中创建一个刻度间隔不相等的轴
How do I create an axis with non-equal tick intervals in D3.js
目前,我有一个带有线性 x 和 y 尺度的基本散点图,用于创建轴,即使用
d3.scaleLinear().domain([0.65, 0.78]).range([0, width])
和
d3.scaleLinear().domain([0, 1]).range([height, 0])
与 d3.axisBottom()
或 d3.axisLeft()
一起创建情节。结果图是
我想修改 y 轴,使刻度线之间的间隔不相等,例如[0.01, 0.05, 0.4, 0.5, 0.9, 0.95, 0.99] 同时仍然保持地块的整体大小(高度没有变化)。理想情况下,情节最终应该看起来像这样(忽略最佳拟合线):
我尝试使用 piecewise plotting 将域值映射到特定范围(高度),但这并不完全有效,因为图的高度被修改了。
有没有办法创建一个具有不相等刻度间隔的轴并仍然保持 svg 的原始形状?
根据要求,这是绘图 (x, y) 的数据:
[
[0.651325, 0.00135],
[0.763999, 0.99865],
[0.663976, 0.01],
[0.669095, 0.02],
[0.672343, 0.03],
[0.674786, 0.04],
[0.676773, 0.05],
[0.678465, 0.06],
[0.679948, 0.07],
[0.681276, 0.08],
[0.682484, 0.09],
[0.683596, 0.1],
[0.684629, 0.11],
[0.685597, 0.12],
[0.68651, 0.13],
[0.687375, 0.14],
[0.688199, 0.15],
[0.688987, 0.16],
[0.689744, 0.17],
[0.690472, 0.18],
[0.691176, 0.19],
[0.691857, 0.2],
[0.692518, 0.21],
[0.693161, 0.22],
[0.693787, 0.23],
[0.694398, 0.24],
[0.694996, 0.25],
[0.695581, 0.26],
[0.696154, 0.27],
[0.696717, 0.28],
[0.69727, 0.29],
[0.697814, 0.3],
[0.69835, 0.31],
[0.698879, 0.32],
[0.699401, 0.33],
[0.699916, 0.34],
[0.700426, 0.35],
[0.700931, 0.36],
[0.70143, 0.37],
[0.701925, 0.38],
[0.702417, 0.39],
[0.702904, 0.4],
[0.703389, 0.41],
[0.703871, 0.42],
[0.70435, 0.43],
[0.704827, 0.44],
[0.705302, 0.45],
[0.705776, 0.46],
[0.706249, 0.47],
[0.70672, 0.48],
[0.707191, 0.49],
[0.707662, 0.5],
[0.708133, 0.51],
[0.708604, 0.52],
[0.709075, 0.53],
[0.709548, 0.54],
[0.710022, 0.55],
[0.710497, 0.56],
[0.710974, 0.57],
[0.711453, 0.58],
[0.711935, 0.59],
[0.71242, 0.6],
[0.712907, 0.61],
[0.713399, 0.62],
[0.713894, 0.63],
[0.714393, 0.64],
[0.714898, 0.65],
[0.715408, 0.66],
[0.715923, 0.67],
[0.716445, 0.68],
[0.716974, 0.69],
[0.71751, 0.7],
[0.718054, 0.71],
[0.718607, 0.72],
[0.71917, 0.73],
[0.719743, 0.74],
[0.720328, 0.75],
[0.720926, 0.76],
[0.721537, 0.77],
[0.722163, 0.78],
[0.722806, 0.79],
[0.723467, 0.8],
[0.724148, 0.81],
[0.724852, 0.82],
[0.72558, 0.83],
[0.726337, 0.84],
[0.727125, 0.85],
[0.727949, 0.86],
[0.728814, 0.87],
[0.729727, 0.88],
[0.730695, 0.89],
[0.731728, 0.9],
[0.73284, 0.91],
[0.734048, 0.92],
[0.735376, 0.93],
[0.736859, 0.94],
[0.738551, 0.95],
[0.740538, 0.96],
[0.742981, 0.97],
[0.746229, 0.98],
[0.751348, 0.99]
]
我设法找到了某种程度上可行的方法。本质上,我们需要创建一个包含所需刻度值的域,然后手动绘制范围。
例如,想要的地块有域
[0,
0.01,
0.02,
0.05,
0.1,
0.25,
0.5,
0.75,
0.9,
0.95,
0.98,
0.99,
1]
我们可以通过遍历域来手动设置我们希望每个刻度线映射到的 y 范围(高度)。
function getYRange(distributionType, yDomain, height) {
let yRange = [];
let pointHeight = height; //height of the svg group
for (let i = 0; i < yDomain.length; i++) {
yRange.push(pointHeight);
if (yDomain[i] >= 0.1 && yDomain[i] <= 0.80) {
delta = 25 + height / yDomain.length;
} else {
delta = -10 + height / yDomain.length;
}
pointHeight -= delta;
}
return yRange;
}
之后,我们只用这个域和范围创建一个刻度,然后用这个域设置的刻度值创建一个轴
const yScale = d3.scaleLinear().domain(yDomain).range(yRange)
const yAxis = d3.axisLeft(yScale).tickValues(yDomain).tickFormat(d3.format('.3f'))
然后调用组元素上的轴,如 g.append("g").call(yAxis)
。
这具有相应地间隔刻度线并使绘图相对直的预期效果。
目前,我有一个带有线性 x 和 y 尺度的基本散点图,用于创建轴,即使用
d3.scaleLinear().domain([0.65, 0.78]).range([0, width])
和
d3.scaleLinear().domain([0, 1]).range([height, 0])
与 d3.axisBottom()
或 d3.axisLeft()
一起创建情节。结果图是
我想修改 y 轴,使刻度线之间的间隔不相等,例如[0.01, 0.05, 0.4, 0.5, 0.9, 0.95, 0.99] 同时仍然保持地块的整体大小(高度没有变化)。理想情况下,情节最终应该看起来像这样(忽略最佳拟合线):
我尝试使用 piecewise plotting 将域值映射到特定范围(高度),但这并不完全有效,因为图的高度被修改了。
有没有办法创建一个具有不相等刻度间隔的轴并仍然保持 svg 的原始形状?
根据要求,这是绘图 (x, y) 的数据:
[
[0.651325, 0.00135],
[0.763999, 0.99865],
[0.663976, 0.01],
[0.669095, 0.02],
[0.672343, 0.03],
[0.674786, 0.04],
[0.676773, 0.05],
[0.678465, 0.06],
[0.679948, 0.07],
[0.681276, 0.08],
[0.682484, 0.09],
[0.683596, 0.1],
[0.684629, 0.11],
[0.685597, 0.12],
[0.68651, 0.13],
[0.687375, 0.14],
[0.688199, 0.15],
[0.688987, 0.16],
[0.689744, 0.17],
[0.690472, 0.18],
[0.691176, 0.19],
[0.691857, 0.2],
[0.692518, 0.21],
[0.693161, 0.22],
[0.693787, 0.23],
[0.694398, 0.24],
[0.694996, 0.25],
[0.695581, 0.26],
[0.696154, 0.27],
[0.696717, 0.28],
[0.69727, 0.29],
[0.697814, 0.3],
[0.69835, 0.31],
[0.698879, 0.32],
[0.699401, 0.33],
[0.699916, 0.34],
[0.700426, 0.35],
[0.700931, 0.36],
[0.70143, 0.37],
[0.701925, 0.38],
[0.702417, 0.39],
[0.702904, 0.4],
[0.703389, 0.41],
[0.703871, 0.42],
[0.70435, 0.43],
[0.704827, 0.44],
[0.705302, 0.45],
[0.705776, 0.46],
[0.706249, 0.47],
[0.70672, 0.48],
[0.707191, 0.49],
[0.707662, 0.5],
[0.708133, 0.51],
[0.708604, 0.52],
[0.709075, 0.53],
[0.709548, 0.54],
[0.710022, 0.55],
[0.710497, 0.56],
[0.710974, 0.57],
[0.711453, 0.58],
[0.711935, 0.59],
[0.71242, 0.6],
[0.712907, 0.61],
[0.713399, 0.62],
[0.713894, 0.63],
[0.714393, 0.64],
[0.714898, 0.65],
[0.715408, 0.66],
[0.715923, 0.67],
[0.716445, 0.68],
[0.716974, 0.69],
[0.71751, 0.7],
[0.718054, 0.71],
[0.718607, 0.72],
[0.71917, 0.73],
[0.719743, 0.74],
[0.720328, 0.75],
[0.720926, 0.76],
[0.721537, 0.77],
[0.722163, 0.78],
[0.722806, 0.79],
[0.723467, 0.8],
[0.724148, 0.81],
[0.724852, 0.82],
[0.72558, 0.83],
[0.726337, 0.84],
[0.727125, 0.85],
[0.727949, 0.86],
[0.728814, 0.87],
[0.729727, 0.88],
[0.730695, 0.89],
[0.731728, 0.9],
[0.73284, 0.91],
[0.734048, 0.92],
[0.735376, 0.93],
[0.736859, 0.94],
[0.738551, 0.95],
[0.740538, 0.96],
[0.742981, 0.97],
[0.746229, 0.98],
[0.751348, 0.99]
]
我设法找到了某种程度上可行的方法。本质上,我们需要创建一个包含所需刻度值的域,然后手动绘制范围。
例如,想要的地块有域
[0,
0.01,
0.02,
0.05,
0.1,
0.25,
0.5,
0.75,
0.9,
0.95,
0.98,
0.99,
1]
我们可以通过遍历域来手动设置我们希望每个刻度线映射到的 y 范围(高度)。
function getYRange(distributionType, yDomain, height) {
let yRange = [];
let pointHeight = height; //height of the svg group
for (let i = 0; i < yDomain.length; i++) {
yRange.push(pointHeight);
if (yDomain[i] >= 0.1 && yDomain[i] <= 0.80) {
delta = 25 + height / yDomain.length;
} else {
delta = -10 + height / yDomain.length;
}
pointHeight -= delta;
}
return yRange;
}
之后,我们只用这个域和范围创建一个刻度,然后用这个域设置的刻度值创建一个轴
const yScale = d3.scaleLinear().domain(yDomain).range(yRange)
const yAxis = d3.axisLeft(yScale).tickValues(yDomain).tickFormat(d3.format('.3f'))
然后调用组元素上的轴,如 g.append("g").call(yAxis)
。
这具有相应地间隔刻度线并使绘图相对直的预期效果。