英文:
How to customise distance between tickers on the 2nd y-axis in BokehJS
问题
我试图使用BokehJS创建一个图形。这个图形需要3个轴(左、右、底部):
如图所示,右侧的y轴看起来相当难看,你无法从底部读取任何数据,因为刻度值都挤在一起。
这是我创建绘图和线条的方式:
function zip(arr1, arr2, floatCast){
var out = {};
if (floatCast){
arr1.map( (val,idx)=>{ out[parseFloat(val)] = arr2[idx]; } );
}
else{
arr1.map( (val,idx)=>{ out[val] = arr2[idx]; } );
}
return out;
}
function createBokehPlot(PNVibe, staticPN, transX, transY){
//清空先前的绘图
$( "#graph-div" ).empty();
//振动下PN与偏移频率的数据源
const source = new Bokeh.ColumnDataSource({
data: { x: Object.keys(PNVibe), y: Object.values(PNVibe) }
});
//静态PN与偏移频率的数据源
const source1 = new Bokeh.ColumnDataSource({
data: { x: Object.keys(staticPN), y: Object.values(staticPN) }
});
//传递线的数据源
const source2 = new Bokeh.ColumnDataSource({
data: { x: transX, y: transY}
});
//设置绘图的x/y范围
var max_offset = Math.max(Object.keys(PNVibe));
const xdr = new Bokeh.Range1d({ start: 1, end: 100000 });
const ydr = new Bokeh.Range1d({ start: -180, end: -50 });
const y2_range = new Bokeh.Range1d({start: 0.001, end: 10});
//创建一个带有一些工具的绘图
const plot = Bokeh.Plotting.figure({
title: '随机数据示例',
tools: "pan,wheel_zoom,box_zoom,reset,save",
toolbar_location: "right",
toolbar_sticky: false,
height: 600,
width: 700,
outerWidth: 800,
legend_location: "top_left",
x_range: xdr,
y_range: ydr,
x_axis_type: "log",
x_axis_label: "偏移频率(Hz)",
y_axis_type: "linear",
y_axis_label: "相位噪声(dBc/Hz)",
extra_y_ranges: {y2_range},
major_label_standoff: 1
});
//在右侧添加第二个y轴
const second_y_axis = new Bokeh.LogAxis({y_range_name:"y2_range", axis_label:'振动轮廓(g^2/Hz)', x_range: xdr, bounds:[0.0001, 10]});
second_y_axis.ticker = new Bokeh.FixedTicker({ticks: [0.0001, 0.001, 0.01, 0.1, 1, 10]});
plot.add_layout(second_y_axis, "right");
//为振动相位噪声添加线
plot.line({ field: "x" }, { field: "y" }, {
source: source,
line_width: 2,
line_color: "red",
legend_label: "振动下的相位噪声"
});
//为静态相位噪声添加线
plot.line({ field: "x" }, { field: "y" }, {
source: source1,
line_width: 2,
line_color: "blue",
legend_label: "静态相位噪声"
});
plot.line({ field: "x" }, { field: "y" }, {
source: source2,
line_width: 2,
line_color: "green",
y_range_name:"y2_range",
legend_label: "传递度"
});
//显示绘图,将其附加到当前部分的末尾
Bokeh.Plotting.show(plot, "#graph-div");
return;
}
//调用函数
var PNVibe = zip([10, 100, 1000], [-95, -100, -105], false);
var staticPN = zip([10, 100, 1000], [-90, -105, -110], false);
var transX = [10, 100, 1000];
var transY = [0.0005, 0.003, 0.05];
createBokehPlot(PNVibe, staticPN, transX, transY);
我的问题是,如何能够使右侧的y轴显示得更好?最好每个刻度之间的距离都相同(即10^0和10^1之间的距离与10^1和10^2之间的距离相同)。
谢谢。
我还在Bokeh论坛上发布了这个问题:这里。
英文:
So I'm trying to create a plot with BokehJS. This plot needs 3 axes (left, right, bottom):
The plot looks like this
As you can see, the right y-axis is pretty ugly, you can't read any data from towards the bottom as the tickers are bunched up.
This is how im creating my plot and lines
function zip(arr1, arr2, floatCast){
var out = {};
if (floatCast){
arr1.map( (val,idx)=>{ out[parseFloat(val)] = arr2[idx]; } );
}
else{
arr1.map( (val,idx)=>{ out[val] = arr2[idx]; } );
}
return out;
}
function createBokehPlot(PNVibe, staticPN, transX, transY){
//empty the previous plot
$( "#graph-div" ).empty();
//Data Source for PN under vibration vs. offset frequency
const source = new Bokeh.ColumnDataSource({
data: { x: Object.keys(PNVibe), y: Object.values(PNVibe) }
});
//Data source for Static PN vs offset frequency
const source1 = new Bokeh.ColumnDataSource({
data: { x: Object.keys(staticPN), y: Object.values(staticPN) }
});
//Data source for Transmissibility line
const source2 = new Bokeh.ColumnDataSource({
data: { x: transX, y: transY}
});
//Set plot x/y ranges
var max_offset = Math.max(Object.keys(PNVibe));
const xdr = new Bokeh.Range1d({ start: 1, end: 100000 });
const ydr = new Bokeh.Range1d({ start: -180, end: -50 });
const y2_range = new Bokeh.Range1d({start: 0.001, end: 10});
// make a plot with some tools
const plot = Bokeh.Plotting.figure({
title: 'Example of random data',
tools: "pan,wheel_zoom,box_zoom,reset,save",
toolbar_location: "right",
toolbar_sticky: false,
height: 600,
width: 700,
outerWidth: 800,
legend_location: "top_left",
x_range: xdr,
y_range: ydr,
x_axis_type:"log",
x_axis_label: "Offset Frequency (Hz)",
y_axis_type: "linear",
y_axis_label: "Phase Noise (dBc/Hz)",
extra_y_ranges: {y2_range},
major_label_standoff: 1
});
//Add the second y axis on the right
const second_y_axis = new Bokeh.LogAxis({y_range_name:"y2_range", axis_label:'Vibration Profile (g^2/Hz)', x_range: xdr, bounds:[0.0001, 10]});
second_y_axis.ticker = new Bokeh.FixedTicker({ticks: [0.0001, 0.001, 0.01, 0.1, 1, 10]})
plot.add_layout(second_y_axis, "right");
// add line for vibraiton phase noise
plot.line({ field: "x" }, { field: "y" }, {
source: source,
line_width: 2,
line_color: "red",
legend_label: "Phase Noise under Vibrations"
});
//add line for static phase noise
plot.line({ field: "x" }, { field: "y" }, {
source: source1,
line_width: 2,
line_color: "blue",
legend_label: "Static Phase Noise"
});
plot.line({ field: "x" }, { field: "y" }, {
source: source2,
line_width: 2,
line_color: "green",
y_range_name:"y2_range",
legend_label: "Transmissibillity"
});
// show the plot, appending it to the end of the current section
Bokeh.Plotting.show(plot, "#graph-div");
return;
}
//Call function
var PNVibe = zip([10, 100, 1000], [-95, -100, -105], false);
var staticPN = zip([10, 100, 1000], [-90, -105, -110], false);
var transX = [10, 100, 1000];
var transY = [0.0005, 0.003, 0.05];
createBokehPlot(PNVibe, staticPN, transX, transY);
My question is, how would I be able to make it so that the right y-axis displays better? Preferably I want each tick to be the same distance from each other (ie. space between 10^0 and 10^1 is the same as space between 10^1 and 10^2)
Thanks
I also posted this on the bokeh forums:Here
答案1
得分: 1
修复了我的问题:
我相信我原始代码中可能存在一些无效的JavaScript,这就是为什么它没有正确渲染的原因。经过几个小时的尝试各种可能的方法,现在已经修复。
// 为y2定义范围
const y2_range = new Bokeh.Range1d({start: 0.0001, end: 10}); // 无法使用数组
// 创建一个带有一些工具的图表
const plot = Bokeh.Plotting.figure({
title: '随机数据示例',
tools: "pan,wheel_zoom,box_zoom,reset,save,hover",
toolbar_location: "right",
toolbar_sticky: false,
height: 600,
width: 700,
outerWidth: 800,
legend_location: "top_left",
x_range: [1, 1000000],
y_range: [-180, -70],
x_axis_type: "log",
x_axis_label: "偏移频率(Hz)",
y_axis_label: "相位噪声(dBc/Hz)",
extra_y_ranges: {"y2_range": y2_range}, // 这是错误的
extra_y_scales: {"y2_range": new Bokeh.LogScale()}, // 这是错误的
major_label_standoff: 5,
});
// 在右侧添加第二个y轴
const second_y_axis = new Bokeh.LogAxis({
y_range_name: "y2_range",
axis_label: '振动谱(g^2/Hz)',
x_range: [1, 1000000],
bounds: [0.0001, 10],
});
plot.add_layout(second_y_axis, "right");
英文:
Fixed my problem:
I believe I may have had some invalid javascript in my original code which is why it wasnt correctly rendering. After hours of messing around with whatever I could think of, it's fixed.
//Define range for y2
const y2_range = new Bokeh.Range1d({start: 0.0001, end: 10}); //Cannot use //array for this
// make a plot with some tools
const plot = Bokeh.Plotting.figure({
title: 'Example of random data',
tools: "pan,wheel_zoom,box_zoom,reset,save,hover",
toolbar_location: "right",
toolbar_sticky: false,
height: 600,
width: 700,
outerWidth: 800,
legend_location: "top_left",
x_range: [1, 1000000],
y_range: [-180, -70],
x_axis_type:"log",
x_axis_label: "Offset Frequency (Hz)",
y_axis_label: "Phase Noise (dBc/Hz)",
extra_y_ranges: {"y2_range": y2_range}, //This was incorrect
extra_y_scales: {"y2_range": new Bokeh.LogScale()}, //This was incorrect
major_label_standoff: 5,
});
//Add the second y axis on the right
const second_y_axis = new Bokeh.LogAxis({
y_range_name:"y2_range",
axis_label:'Vibration Profile (g^2/Hz)',
x_range: [1, 1000000],
bounds:[0.0001, 10],
});
plot.add_layout(second_y_axis, "right");
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论