gpt4 book ai didi

javascript - Python点击事件的Plotly(离线)

转载 作者:行者123 更新时间:2023-11-29 23:56:07 25 4
gpt4 key购买 nike

是否可以将点击事件添加到 Plotly 散点图(Python 中的离线模式)?

例如,我想在单击时更改一组散点的形状。

到目前为止我尝试了什么

我从网站上阅读其他问题(没有明确答案)的理解是,我可能必须生成 html,然后在事后通过放入 javascript 代码对其进行编辑?所以我可以编写一个 javascript 函数,将它保存到 my_js.js,然后从 html 链接到它?

最佳答案

我一直在 plotly 中使用离线绘图进行一些工作,并且遇到了同样的挑战。

这是我想出的一个拼凑,我证明是对其他人的启发。

一些限制:

  • 假设您在单个 html 文件中有单个图的离线输出。
  • 假定您的事件与事件处理程序的名称相同。
  • 需要 Beautiful Soup 4。
  • 假设您已经安装了 lxml。
  • 使用 Plotly 2.2.2 开发

代码片段:

import bs4

def add_custom_plotly_events(
filename,
events = {
"plotly_click": "function plotly_click(data) { console.log(data); }",
"plotly_hover": "function plotly_hover(data) { console.log(data); }"
},
prettify_html = True
):

# what the value we're looking for the javascript
find_string = "Plotly.newPlot"

# stop if we find this value
stop_string = "then(function(myPlot)"

def locate_newplot_script_tag(soup):
scripts = soup.find_all('script')
script_tag = soup.find_all(string=re.compile(find_string))

if len(script_tag) == 0:
raise ValueError("Couldn't locate the newPlot javascript in {}".format(filename))
elif len(script_tag) > 1:
raise ValueError("Located multiple newPlot javascript in {}".format(filename))

if script_tag[0].find(stop_string) > -1:
raise ValueError("Already updated javascript, it contains:", stop_string)

return script_tag[0]

def split_javascript_lines(new_plot_script_tag):
return new_plot_script_tag.string.split(";")

def find_newplot_creation_line(javascript_lines):
for index, line in enumerate(javascript_lines):
if line.find(find_string) > -1:
return index, line
raise ValueError("Missing new plot creation in javascript, couldn't find:", find_string)

def join_javascript_lines(javascript_lines):
# join the lines with javascript line terminator ;
return ";".join(javascript_lines)

def register_on_events(events):
on_events_registration = []
for function_name in events:
on_events_registration.append("myPlot.on('{}', {})".format(
function_name, function_name
))
return on_events_registration

# load the file
with open(filename) as inf:
txt = inf.read()
soup = bs4.BeautifulSoup(txt, "lxml")

new_plot_script_tag = locate_newplot_script_tag(soup)

javascript_lines = split_javascript_lines(new_plot_script_tag)

line_index, line_text = find_newplot_creation_line(javascript_lines)

on_events_registration = register_on_events(events)

# replace whitespace characters with actual whitespace
# using + to concat the strings as {} in format
# causes fun times with {} as the brackets in js
# could possibly overcome this with in ES6 arrows and such
line_text = line_text + ".then(function(myPlot) { " + join_javascript_lines(on_events_registration) +" })".replace('\n', ' ').replace('\r', '')

# now add the function bodies we've register in the on handles
for function_name in events:
javascript_lines.append(events[function_name])

# update the specific line
javascript_lines[line_index] = line_text

# update the text of the script tag
new_plot_script_tag.string.replace_with(join_javascript_lines(javascript_lines))

# save the file again
with open(filename, "w") as outf:
# tbh the pretty out is still ugly af
if prettify_html:
for line in soup.prettify(formatter = None):
outf.write(str(line))
else:
outf.write(str(soup))

关于javascript - Python点击事件的Plotly(离线),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41619708/

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