gpt4 book ai didi

python - 在 plotly 弹出窗口中放置图表

转载 作者:太空狗 更新时间:2023-10-29 21:23:45 25 4
gpt4 key购买 nike

我正在为 R 使用 plotly,尽管我也愿意使用 Python 版本。当我将鼠标悬停在数据点上时,有没有办法让弹出窗口包含另一个图表?理想情况下,图表将根据数据创建,但我可以使用静态图像作为后备。

我不确定从哪里开始,并为没有 MWE 提前道歉。

最佳答案

解决方案 1:坚持使用 R

感谢@MLavoie。以下示例使用纯 R创建两个 plotly ,“主 plotly ”和对第一个 plotly 的悬停事件使用react的“悬停”。

library(shiny)
library(plotly)

ui <- fluidPage(
plotlyOutput("mainplot"),
plotlyOutput("hover")
)

server <- function(input, output) {
output$mainplot <- renderPlotly({
# https://plot.ly/r/
d <- diamonds[sample(nrow(diamonds), 1000), ]
plot_ly(d, x = carat, y = price, text = paste("Clarity: ", clarity), mode = "markers", color = carat, size = carat, source="main")
})

output$hover <- renderPlotly({
eventdat <- event_data('plotly_hover', source="main") # get event data from source main
if(is.null(eventdat) == T) return(NULL) # If NULL dont do anything
point <- as.numeric(eventdat[['pointNumber']]) # Index of the data point being charted

# draw plot according to the point number on hover
plot_ly( x = c(1,2,3), y = c(point, point*2, point*3), mode = "scatter")
})
}
shinyApp(ui, server)

此示例使用 shiny binds for plotly . 对于每个悬停事件,一个 POST请求发送到服务器,然后服务器将更新弹出图表。它的效率非常低,因此在低速连接上可能无法正常工作。

以上代码只是为了演示,还没有经过测试。查看一个有效且复杂得多的示例 here (与 source )。

解决方案 2:Javascript

是的,您可以使用 plotly Javascript API 来做到这一点.

简答

  1. 使用 R 创建图表或 Python或任何其他支持的语言。
  2. 将图形插入新的 HTML 页面并添加回调函数,如下例所示。如果你对DOM有很好的了解,您也可以将 JS 添加到原始 HTML 而不是创建新的 HTML。
  3. 在回调函数中绘制弹出图形,回调函数接受包含悬停数据点数据的参数。

详情

正如@MLavoie 提到的,plotly.hover-events 中显示了一个很好的示例

让我们深入研究代码。在 JS 文件中,有一个简单的回调函数附加到 Plot :

Plot.onHover = function(message) {
var artist = message.points[0].x.toLowerCase().replace(/ /g, '-');

var imgSrc = blankImg;
if(artistToUrl[artist] !== undefined) imgSrc = artistToUrl[artist];

Plot.hoverImg.src = imgSrc;
};

以上,artistToUrl是一个充满 base64 字符串的巨大对象,我不会将其粘贴到此处以溢出帖子。但是您可以在示例页面的 JS 选项卡下看到它。它有这样的结构:

var artistToUrl = { 'bob-dylan': 'data:image/jpeg;base64,/...',...}

工作示例:

为了演示,我准备了一个简单的例子here (点击试用):

<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<iframe id="plot" style="width: 900px; height: 600px;" src="https://plot.ly/~jackp/10816.embed" seamless></iframe>
<div id="myDiv"></div>
<script>
(function main() {
var Plot = { id: 'plot', domain: 'https://plot.ly' };
Plot.onHover = function(message) {
var y = message.points[0].y; /*** y value of the data point(bar) under hover ***/
var line1 = {
x: [0.25,0.5,1], /*** dummy x array in popup-chart ***/
y: [1/y, 2, y], /*** dummy y array in popup-chart ***/
mode: 'lines+markers'
};
var layout = {
title:'Popup graph on hover',
height: 400,
width: 480
};
Plotly.newPlot('myDiv', [ line1 ], layout); // this finally draws your popup-chart
};
Plot.init = function init() {
var pinger = setInterval(function() {
Plot.post({task: 'ping'});
}, 500);

function messageListener(e) {
var message = e.data;
if(message.pong) {
console.log('Initial pong, frame is ready to receive');
clearInterval(pinger);
Plot.post({
'task': 'listen',
'events': ['hover']
});
}
else if(message.type === 'hover') {
Plot.onHover(message);
}
}
window.removeEventListener('message', messageListener);
window.addEventListener('message', messageListener);
};
Plot.post = function post(o) {
document.getElementById(Plot.id).contentWindow.postMessage(o, Plot.domain);
};

Plot.init();
})();
</script>
</body>
</html>

这是从 poltly.hover-events 修改而来的 python 的例子。我没有弹出图像,而是更改了 onhover回调以绘制基于 y 的曲线每个柱的值。

主图由python生成,插入此处为iframe .您可以使用任何语言制作自己的语言,包括 R .在此页面中,我们添加一个 <div id="myDiv"></div>并使用 plotly.js 在其中绘制弹出图表。

将R数据框导出到JS环境

Shiny 使用 jsonlite转换 R反对 json并将它们发送给客户。我们可以使用相同的机制来打包和发送我们的数据帧,以便 JS 回调可以使用数据来呈现弹出图表。

服务器.r

output$json <- reactive({
paste('<script>data =', RJSONIO::toJSON(your_data_frame, byrow=T, colNames=T),'</script>')

用户界面

fluidPage(..., htmlOutput("json"), ...)

在JS回调函数中,可以使用data与任何其他 JS 对象一样。

更多细节去herehere .

关于python - 在 plotly 弹出窗口中放置图表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36755712/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com