在 plotly R 中根据坐标值而不是像素设置标记大小
Set marker size based on coordinate values, not pixels, in plotly R
这个 post - Set marker size in plotly - 不幸的是没有帮助我寻找,并且是我能找到的关于该主题的唯一 post。根据关于散点图大小参数的 plotly 文档:
"size (number or array of numbers greater than or equal to 0), default: 6, Sets the marker size (in px)"
(像素)对我来说是个问题。我想创建一个绘图,其中标记大小基于坐标值而不是像素,这样我就可以增加图形的大小(例如,通过全屏显示)并且点的大小也会增加。我目前的代码示例:
library(plotly)
mydf <- data.frame(x = rep(1:20, times = 20), y = rep(1:20, each = 20),
thesize = 10)
plot_ly(mydf) %>%
add_trace(x = ~x, y = ~y, type = 'scatter', mode = 'markers',
marker = list(symbol = 'hexagon', size = ~thesize, opacity = 0.6))
如果您在 R 中创建此图,然后通过拖动 Rstudio 查看器 window 或以其他方式使图变大或变小,您会注意到标记保持完全相同大小(10 像素),这令人沮丧。如果我能让这些标记的直径 == 1(在 x 轴上)而不是设置为多个像素,我会很高兴。这可能吗?
非常感谢任何帮助!!!
让我们从具有已定义轴范围的图开始。
p <- plot_ly() %>% layout(xaxis = list(range = c(1, 5)))
现在添加一个 JavaScript 事件侦听器,它捕获情节布局中的任何变化
javascript <- "
var myPlot = document.getElementsByClassName('plotly')[0];
function resize(eventdata) {
// magic happens here
}
myPlot.on('plotly_relayout', function(eventdata) {
resize(eventdata);
});
"
p <- htmlwidgets::prependContent(p,
onStaticRenderComplete(javascript))
p
事件通过 eventdata
从那里我们可以获得新的轴范围。
eventdata['xaxis.range[1]']
由于我们事先不知道地块的大小,所以我们通过轴线的大小来确定
var plot_width = Plotly.d3.select('.xlines-above').node().getBBox()['width'];
我们需要手动调用一次事件以确保绘图正确初始化
初始剧情
放大
完整的 R 代码
library("plotly")
library("htmlwidgets")
p <- plot_ly() %>%
add_trace(x = c(1.5, 3, 4.2),
y = c(-2, 1, 2),
type = 'scatter',
mode = 'lines+markers',
showlegend = F) %>%
add_trace(x = c(2, 3, 4.2),
y = c(2, 0, -1),
type = 'scatter',
mode = 'lines+markers',
showlegend = F) %>%
add_trace(x = c(1.5, 3, 4.2),
y = c(1, 0.5, 1),
type = 'scatter',
mode = 'markers',
showlegend = F) %>%
layout(xaxis = list(range = c(1, 5)))
javascript <- "
marker_size = 0.5; // x-axis units
var myPlot = document.getElementsByClassName('plotly')[0];
function resize(eventdata) {
var xaxis_stop = 5;
var xaxis_start = 1;
var plot_width = Plotly.d3.select('.xlines-above').node().getBBox()['width'];
if (eventdata['xaxis.range[1]'] !== undefined) {
var update = {'marker.size': marker_size * plot_width / (eventdata['xaxis.range[1]'] - eventdata['xaxis.range[0]'])};
} else {
var update = {'marker.size': marker_size * plot_width / (xaxis_stop - xaxis_start)};
}
Plotly.restyle(myPlot, update, 2);
}
resize({eventdata: {}});
myPlot.on('plotly_relayout', function(eventdata) {
resize(eventdata);
});
"
p <- htmlwidgets::prependContent(p,
onStaticRenderComplete(javascript))
p
交互式JavaScript示例
- 您可以从定义的 height/width 图表和定义的轴范围开始,这样您就可以知道一个轴单位有多少像素。
- 您的标记的大小最初是您想要的大小。
- 每当用户更改轴范围时,将触发
plotly_relayout
事件,您可以从 xaxis.range[1]
(开始)和 [=20] 中的 eventdata
检索新范围=](结束)
- 根据新范围,您可以
relayout
您的标记大小。
var plot_width = 500;
var plot_height = 500;
var margin_l = 100;
var margin_r = 100;
marker_size = 0.5; // x-axis units
xaxis_start = 1;
xaxis_stop = 5;
var trace1 = {
x: [1.5, 2, 3, 4],
y: [10, 15, 13, 17],
mode: "markers",
marker: {
size: marker_size *
(plot_width - margin_l - margin_r) /
(xaxis_stop - xaxis_start)
},
showlegend: false
};
var trace2 = {
x: [2, 3, 4, 4.5],
y: [16, 5, 11, 10],
mode: "lines"
};
var trace3 = {
x: [1.5, 2, 3, 4],
y: [12, 9, 15, 12],
mode: "lines+markers",
showlegend: false
};
var data = [trace1, trace2, trace3];
var layout = {
width: plot_width,
height: plot_height,
margin: {
l: margin_l,
r: margin_r
},
xaxis: {
range: [1, 5]
},
showlegend: false
};
Plotly.newPlot("myDiv", data, layout);
var refplot = document.getElementById("myDiv");
refplot.on("plotly_relayout", function(eventdata) {
if (eventdata["xaxis.range[1]"] !== undefined) {
var update = {
"marker.size": marker_size *
(plot_width - margin_l - margin_r) /
(eventdata["xaxis.range[1]"] - eventdata["xaxis.range[0]"])
};
} else {
var update = {
"marker.size": marker_size *
(plot_width - margin_l - margin_r) /
(xaxis_stop - xaxis_start)
};
}
Plotly.restyle("myDiv", update, 0);
});
<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<div id="myDiv"></div>
</body>
这个 post - Set marker size in plotly - 不幸的是没有帮助我寻找,并且是我能找到的关于该主题的唯一 post。根据关于散点图大小参数的 plotly 文档:
"size (number or array of numbers greater than or equal to 0), default: 6, Sets the marker size (in px)"
(像素)对我来说是个问题。我想创建一个绘图,其中标记大小基于坐标值而不是像素,这样我就可以增加图形的大小(例如,通过全屏显示)并且点的大小也会增加。我目前的代码示例:
library(plotly)
mydf <- data.frame(x = rep(1:20, times = 20), y = rep(1:20, each = 20),
thesize = 10)
plot_ly(mydf) %>%
add_trace(x = ~x, y = ~y, type = 'scatter', mode = 'markers',
marker = list(symbol = 'hexagon', size = ~thesize, opacity = 0.6))
如果您在 R 中创建此图,然后通过拖动 Rstudio 查看器 window 或以其他方式使图变大或变小,您会注意到标记保持完全相同大小(10 像素),这令人沮丧。如果我能让这些标记的直径 == 1(在 x 轴上)而不是设置为多个像素,我会很高兴。这可能吗?
非常感谢任何帮助!!!
让我们从具有已定义轴范围的图开始。
p <- plot_ly() %>% layout(xaxis = list(range = c(1, 5)))
现在添加一个 JavaScript 事件侦听器,它捕获情节布局中的任何变化
javascript <- " var myPlot = document.getElementsByClassName('plotly')[0]; function resize(eventdata) { // magic happens here } myPlot.on('plotly_relayout', function(eventdata) { resize(eventdata); }); " p <- htmlwidgets::prependContent(p, onStaticRenderComplete(javascript)) p
事件通过
eventdata
从那里我们可以获得新的轴范围。eventdata['xaxis.range[1]']
由于我们事先不知道地块的大小,所以我们通过轴线的大小来确定
var plot_width = Plotly.d3.select('.xlines-above').node().getBBox()['width'];
我们需要手动调用一次事件以确保绘图正确初始化
初始剧情
放大
library("plotly")
library("htmlwidgets")
p <- plot_ly() %>%
add_trace(x = c(1.5, 3, 4.2),
y = c(-2, 1, 2),
type = 'scatter',
mode = 'lines+markers',
showlegend = F) %>%
add_trace(x = c(2, 3, 4.2),
y = c(2, 0, -1),
type = 'scatter',
mode = 'lines+markers',
showlegend = F) %>%
add_trace(x = c(1.5, 3, 4.2),
y = c(1, 0.5, 1),
type = 'scatter',
mode = 'markers',
showlegend = F) %>%
layout(xaxis = list(range = c(1, 5)))
javascript <- "
marker_size = 0.5; // x-axis units
var myPlot = document.getElementsByClassName('plotly')[0];
function resize(eventdata) {
var xaxis_stop = 5;
var xaxis_start = 1;
var plot_width = Plotly.d3.select('.xlines-above').node().getBBox()['width'];
if (eventdata['xaxis.range[1]'] !== undefined) {
var update = {'marker.size': marker_size * plot_width / (eventdata['xaxis.range[1]'] - eventdata['xaxis.range[0]'])};
} else {
var update = {'marker.size': marker_size * plot_width / (xaxis_stop - xaxis_start)};
}
Plotly.restyle(myPlot, update, 2);
}
resize({eventdata: {}});
myPlot.on('plotly_relayout', function(eventdata) {
resize(eventdata);
});
"
p <- htmlwidgets::prependContent(p,
onStaticRenderComplete(javascript))
p
交互式JavaScript示例
- 您可以从定义的 height/width 图表和定义的轴范围开始,这样您就可以知道一个轴单位有多少像素。
- 您的标记的大小最初是您想要的大小。
- 每当用户更改轴范围时,将触发
plotly_relayout
事件,您可以从xaxis.range[1]
(开始)和 [=20] 中的eventdata
检索新范围=](结束) - 根据新范围,您可以
relayout
您的标记大小。
var plot_width = 500;
var plot_height = 500;
var margin_l = 100;
var margin_r = 100;
marker_size = 0.5; // x-axis units
xaxis_start = 1;
xaxis_stop = 5;
var trace1 = {
x: [1.5, 2, 3, 4],
y: [10, 15, 13, 17],
mode: "markers",
marker: {
size: marker_size *
(plot_width - margin_l - margin_r) /
(xaxis_stop - xaxis_start)
},
showlegend: false
};
var trace2 = {
x: [2, 3, 4, 4.5],
y: [16, 5, 11, 10],
mode: "lines"
};
var trace3 = {
x: [1.5, 2, 3, 4],
y: [12, 9, 15, 12],
mode: "lines+markers",
showlegend: false
};
var data = [trace1, trace2, trace3];
var layout = {
width: plot_width,
height: plot_height,
margin: {
l: margin_l,
r: margin_r
},
xaxis: {
range: [1, 5]
},
showlegend: false
};
Plotly.newPlot("myDiv", data, layout);
var refplot = document.getElementById("myDiv");
refplot.on("plotly_relayout", function(eventdata) {
if (eventdata["xaxis.range[1]"] !== undefined) {
var update = {
"marker.size": marker_size *
(plot_width - margin_l - margin_r) /
(eventdata["xaxis.range[1]"] - eventdata["xaxis.range[0]"])
};
} else {
var update = {
"marker.size": marker_size *
(plot_width - margin_l - margin_r) /
(xaxis_stop - xaxis_start)
};
}
Plotly.restyle("myDiv", update, 0);
});
<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<div id="myDiv"></div>
</body>