如何利用python plotly实现多html合并后共享或联动按钮

#我通过以下代码实现了plotly生成的多个离线html图表合并展示在一个html文件中,每个图表都有按钮,目前的代码只能实现一个按钮控制一张图,如何共享按钮或者联动按钮,实现一次点击所有图表都能响应呢?希望有朋友能帮助解答

import numpy as np
import plotly
import plotly.graph_objects as go

fichier_html_graphs=open("DASHBOARD.html",'w')
fichier_html_graphs.write("<html><head></head><body>"+"\n")

i=0
while 1:
    if i<=5:
        i=i+1


        #______________________________--Plotly--______________________________________
        # 定义三组数据
        x0 = np.random.normal(2, 0.4, 400)
        y0 = np.random.normal(2, 0.4, 400)
        x1 = np.random.normal(3, 0.6, 600)
        y1 = np.random.normal(6, 0.4, 400)
        x2 = np.random.normal(4, 0.2, 200)
        y2 = np.random.normal(4, 0.4, 200)

        # 先绘制散点图
        trace0 = go.Scatter(
            x=x0,
            y=y0,
            mode='markers',
            marker=dict(color='#835AF1')
        )
        trace1 = go.Scatter(
            x=x1,
            y=y1,
            mode='markers',
            marker=dict(color='#7FA6EE')
        )
        trace2 = go.Scatter(
            x=x2,
            y=y2,
            mode='markers',
            marker=dict(color='#B8F7D4')
        )
        data = [trace0, trace1, trace2]

        # 绘制三个圆型图
        cluster0 = [dict(type='circle',
                         xref='x', yref='y',
                         x0=min(x0), y0=min(y0),
                         x1=max(x0), y1=max(y0),
                         opacity=.25,
                         line=dict(color='#835AF1'),
                         fillcolor='#835AF1')]
        cluster1 = [dict(type='circle',
                         xref='x', yref='y',
                         x0=min(x1), y0=min(y1),
                         x1=max(x1), y1=max(y1),
                         opacity=.25,
                         line=dict(color='#7FA6EE'),
                         fillcolor='#7FA6EE')]
        cluster2 = [dict(type='circle',
                         xref='x', yref='y',
                         x0=min(x2), y0=min(y2),
                         x1=max(x2), y1=max(y2),
                         opacity=.25,
                         line=dict(color='#B8F7D4'),
                         fillcolor='#B8F7D4')]

        #设置五个按钮
        updatemenus = list([
            dict(type="buttons",
                 buttons=list([
                     dict(label='None',
                          method='relayout',
                          args=['shapes', []]),
                     dict(label='Cluster 0',
                          method='relayout',
                          args=['shapes', cluster0]),
                     dict(label='Cluster 1',
                          method='relayout',
                          args=['shapes', cluster1]),
                     dict(label='Cluster 2',
                          method='relayout',
                          args=['shapes', cluster2]),
                     dict(label='All',
                          method='relayout',
                          args=['shapes', cluster0 + cluster1 + cluster2])
                 ]),
                 )
        ])

        layout = dict(title='Highlight Clusters', showlegend=False,
                      updatemenus=updatemenus)

        fig = dict(data=data, layout=layout)
        fig = go.Figure(data=data, layout=layout)
        plotly.offline.plot(fig, filename='Chart_'+str(i)+'.html',auto_open=False)
        fichier_html_graphs.write("  <object data=\""+'Chart_'+str(i)+'.html'+"\" width=\"650\" height=\"500\"></object>"+"\n")
    else:
        break

fichier_html_graphs.write("</body></html>")

img

援引通义千问:
要实现共享或联动按钮,可以将每个图表的按钮都添加到一个共享的updatemenus中,然后在每个图表的layout中引用这个共享的updatemenus。这样,每个图表的按钮都可以控制所有图表的显示。
以下是修改后的代码示例:

import numpy as np
import plotly
import plotly.graph_objects as go

fichier_html_graphs=open("DASHBOARD.html",'w')
fichier_html_graphs.write("<html><head></head><body>"+"\n")

updatemenus = list([
    dict(type="buttons",
         buttons=list([
             dict(label='None',
                  method='relayout',
                  args=['shapes', []]),
             dict(label='Cluster 0',
                  method='relayout',
                  args=['shapes', cluster0]),
             dict(label='Cluster 1',
                  method='relayout',
                  args=['shapes', cluster1]),
             dict(label='Cluster 2',
                  method='relayout',
                  args=['shapes', cluster2]),
             dict(label='All',
                  method='relayout',
                  args=['shapes', cluster0 + cluster1 + cluster2])
         ]),
         )
])

i=0
while 1:
    if i<=5:
        i=i+1
        #______________________________--Plotly--______________________________________
        # 定义三组数据
        x0 = np.random.normal(2, 0.4, 400)
        y0 = np.random.normal(2, 0.4, 400)
        x1 = np.random.normal(3, 0.6, 600)
        y1 = np.random.normal(6, 0.4, 400)
        x2 = np.random.normal(4, 0.2, 200)
        y2 = np.random.normal(4, 0.4, 200)
        # 先绘制散点图
        trace0 = go.Scatter(
            x=x0,
            y=y0,
            mode='markers',
            marker=dict(color='#835AF1')
        )
        trace1 = go.Scatter(
            x=x1,
            y=y1,
            mode='markers',
            marker=dict(color='#7FA6EE')
        )
        trace2 = go.Scatter(
            x=x2,
            y=y2,
            mode='markers',
            marker=dict(color='#B8F7D4')
        )
        data = [trace0, trace1, trace2]
        # 绘制三个圆型图
        cluster0 = [dict(type='circle',
                         xref='x', yref='y',
                         x0=min(x0), y0=min(y0),
                         x1=max(x0), y1=max(y0),
                         opacity=.25,
                         line=dict(color='#835AF1'),
                         fillcolor='#835AF1')]
        cluster1 = [dict(type='circle',
                         xref='x', yref='y',
                         x0=min(x1), y0=min(y1),
                         x1=max(x1), y1=max(y1),
                         opacity=.25,
                         line=dict(color='#7FA6EE'),
                         fillcolor='#7FA6EE')]
        cluster2 = [dict(type='circle',
                         xref='x', yref='y',
                         x0=min(x2), y0=min(y2),
                         x1=max(x2), y1=max(y2),
                         opacity=.25,
                         line=dict(color='#B8F7D4'),
                         fillcolor='#B8F7D4')]
        #设置五个按钮
        layout = dict(title='Highlight Clusters', showlegend=False,
                      updatemenus=updatemenus)
 
        fig = dict(data=data, layout=layout)
        fig = go.Figure(data=data, layout=layout)
        plotly.offline.plot(fig, filename='Chart_'+str(i)+'.html',auto_open=False)
        fichier_html_graphs.write("  <object data=\""+'Chart_'+str(i)+'.html'+"\" width=\"650\" height=\"500\"></object>"+"\n")
    else:
        break

fichier_html_graphs.write("</body></html>")

监听点击事件同时修改这几个图表。

该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
要实现多个Plotly图表之间的共享或联动按钮,你可以使用Plotly的JavaScript事件处理和回调函数来实现。下面修改后的代码:

import numpy as np
import plotly
import plotly.graph_objects as go

# 创建一个共享的按钮回调函数
button_callback = """
    function updateCharts(button) {
        var shapes = [];
        var buttonLabel = button.label;

        // 根据按钮标签设置对应的形状
        if (buttonLabel === 'None') {
            shapes = [];
        } else if (buttonLabel === 'Cluster 0') {
            shapes = %s;
        } else if (buttonLabel === 'Cluster 1') {
            shapes = %s;
        } else if (buttonLabel === 'Cluster 2') {
            shapes = %s;
        } else if (buttonLabel === 'All') {
            shapes = %s;
        }

        // 更新所有图表的形状
        for (var i = 0; i < charts.length; i++) {
            var chart = charts[i];
            Plotly.relayout(chart, 'shapes', shapes);
        }
    }
"""

fichier_html_graphs = open("DASHBOARD.html", 'w')
fichier_html_graphs.write("<html><head></head><body>" + "\n")

i = 0
shapes = []  # 存储所有图表的形状

while i <= 5:
    i = i + 1
    # ------------------------------ Plotly ----------------------------------
    # 定义三组数据...

    # 设置五个按钮...
    cluster0 = [dict(type='circle',
                     xref='x', yref='y',
                     x0=min(x0), y0=min(y0),
                     x1=max(x0), y1=max(y0),
                     opacity=.25,
                     line=dict(color='#835AF1'),
                     fillcolor='#835AF1')]
    cluster1 = [dict(type='circle',
                     xref='x', yref='y',
                     x0=min(x1), y0=min(y1),
                     x1=max(x1), y1=max(y1),
                     opacity=.25,
                     line=dict(color='#7FA6EE'),
                     fillcolor='#7FA6EE')]
    cluster2 = [dict(type='circle',
                     xref='x', yref='y',
                     x0=min(x2), y0=min(y2),
                     x1=max(x2), y1=max(y2),
                     opacity=.25,
                     line=dict(color='#B8F7D4'),
                     fillcolor='#B8F7D4')]

    button_callback_script = button_callback % (cluster0, cluster1, cluster2, cluster0 + cluster1 + cluster2)

    # 创建一个HTML容器来显示图表,并为每个容器添加一个唯一的ID
    chart_div_id = "chart_" + str(i)
    fichier_html_graphs.write("<div id='" + chart_div_id + "'></div>" + "\n")

    # 将图表的形状和ID添加到shapes列表中
    shapes.append({
        'shapes': shapes,
        'chartDivId': chart_div_id
    })

fichier_html_graphs.write("</body></html>")
fichier_html_graphs.close()

# 创建一个JavaScript回调函数,将shapes和charts传递给共享按钮回调
callback_script = """
    <script>
        var shapes = %s;
        var charts = [];

        // 初始化图表并存储到charts列表中
        for (var i = 0; i < shapes.length; i++) {
            var shape = shapes[i];
            var chartDivId = shape.chartDivId;
            var chart = document.getElementById(chartDivId);
            charts.push(chart);
        }

        // 创建共享按钮的回调函数
        function buttonCallback(button) {
            %s
        }

        // 获取所有共享按钮
        var buttons = document.getElementsByClassName('js-plotly-button');

        // 为每个按钮添加点击事件处理程序
        for (var i = 0; i < buttons.length; i++) {
            var button = buttons[i];
            button.onclick = function() {
                buttonCallback(this);
            };
        }
    </script>
"""

# 将shapes和按钮回调函数写入DASHBOARD.html文件
html_file = open("DASHBOARD.html", 'a')
html_file.write(callback_script % (shapes, button_callback_script))
html_file.close()

如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

【以下回答由 GPT 生成】

我可以为您提供如何使用Python的Plotly实现多个HTML图表的合并和按钮联动的解决方案。

为了实现这个功能,您可以按照以下步骤进行操作:

  1. 首先,确保您已经安装了Plotly库。可以使用以下命令在您的Python环境中安装Plotly:

python pip install plotly

  1. 接下来,您需要使用Plotly创建多个图表。在您的代码中,已经包含了创建三个散点图的示例代码。您可以继续在此基础上创建更多的图表。

  2. 为了将这些图表合并到一个HTML文件中,您可以使用Plotly的subplot()函数。该函数接受一个参数rowscols,用于指定子图的布局。在您的代码中,您可以考虑将图表排列成两行三列的布局。

python fig = plotly.subplots.make_subplots(rows=2, cols=3)

  1. 然后,您可以使用add_trace()方法将每个图表添加到子图布局中。

python fig.add_trace(trace0, row=1, col=1) fig.add_trace(trace1, row=1, col=2) fig.add_trace(trace2, row=1, col=3)

在这个示例中,我们将三个图表分别添加到第一行的三个列上。您可以根据自己的需求进行调整。

  1. 然后,您可以为每个图表添加一个按钮。使用Plotly的Button()类创建一个按钮对象,并指定按钮的标签和点击时触发的动作。

python button = plotly.graph_objs.layout.updatemenu.buttons( label='按钮标签', method='update', args=[{'visible': [True, False, False]}, {'title': '标题'}] )

在这个示例中,我们创建了一个标签为“按钮标签”的按钮,并定义了点击按钮时显示哪些图表以及更新标题等操作。

  1. 将按钮添加到图表布局中的适当位置。

python fig.update_layout( updatemenus=[plotly.graph_objs.layout.Updatemenu(buttons=[button])] )

在这个示例中,我们将按钮添加到图表的“updatemenus”布局中。

  1. 最后,将图表对象写入HTML文件中。

python plotly.offline.plot(fig, filename='DASHBOARD.html')

这将生成一个名为“DASHBOARD.html”的HTML文件,其中包含合并的图表和按钮。

请注意,上述代码只是一个示例,您可以根据自己的需求进行修改和调整。同时,您可以使用不同的布局和按钮配置来实现您想要的效果。

希望以上解决方案对您有所帮助。如果您有任何问题,请随时提问。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

<!DOCTYPE html>
<html>
<head>
    <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<div id="plotly-buttons">
    <button id="cluster0">Cluster 0</button>
    <button id="cluster1">Cluster 1</button>
    <button id="cluster2">Cluster 2</button>
    <button id="reset">Reset</button>
</div>
<div id="plotly-graphs">
    <!-- 这里将插入生成的图表 -->
</div>
<script>
// 获取按钮元素
var cluster0Button = document.getElementById('cluster0');
var cluster1Button = document.getElementById('cluster1');
var cluster2Button = document.getElementById('cluster2');
var resetButton = document.getElementById('reset');
// 获取图表容器元素
var graphContainer = document.getElementById('plotly-graphs');
// 创建图表的数据和布局
var data = [...]; // 你的图表数据
var layout = {...}; // 你的图表布局
// 创建图表
var fig = {
    data: data,
    layout: layout
};
// 渲染初始图表
Plotly.newPlot(graphContainer, fig);
// 添加按钮事件监听器
cluster0Button.addEventListener('click', function() {
    // 根据需要更新图表数据或布局
    // 这里示例假设有一个名为cluster0Shapes的属性来存储Cluster 0的形状
    fig.layout.shapes = cluster0Shapes;
    Plotly.react(graphContainer, fig);
});
cluster1Button.addEventListener('click', function() {
    // 类似地,根据需要更新图表数据或布局
    // 这里示例假设有一个名为cluster1Shapes的属性来存储Cluster 1的形状
    fig.layout.shapes = cluster1Shapes;
    Plotly.react(graphContainer, fig);
});
cluster2Button.addEventListener('click', function() {
    // 类似地,根据需要更新图表数据或布局
    // 这里示例假设有一个名为cluster2Shapes的属性来存储Cluster 2的形状
    fig.layout.shapes = cluster2Shapes;
    Plotly.react(graphContainer, fig);
});
resetButton.addEventListener('click', function() {
    // 重置图表,去掉所有形状
    fig.layout.shapes = [];
    Plotly.react(graphContainer, fig);
});
</script>
</body>
</html>

参考结合GPT4.0、文心一言,如有帮助,恭请采纳。
你需要将这些图表放在一个Figure对象中,然后在这个Figure对象上添加一个按钮。
下面是一个示例代码,期望可以帮助到你:

import plotly.graph_objects as go  
import numpy as np  
  
# 定义三组数据  
x0 = np.random.normal(2, 0.4, 400)  
y0 = np.random.normal(2, 0.4, 400)  
x1 = np.random.normal(3, 0.6, 600)  
y1 = np.random.normal(6, 0.4, 400)  
x2 = np.random.normal(4, 0.2, 200)  
y2 = np.random.normal(4, 0.4, 200)  
  
# 先绘制散点图  
trace0 = go.Scatter(  
    x=x0,  
    y=y0,  
    mode='markers',  
    marker=dict(color='#835AF1')  
)  
trace1 = go.Scatter(  
    x=x1,  
    y=y1,  
    mode='markers',  
    marker=dict(color='#7FA6EE')  
)  
trace2 = go.Scatter(  
    x=x2,  
    y=y2,  
    mode='markers',  
    marker=dict(color='#B8F7D4')  
)  
data = [trace0, trace1, trace2]  
  
# 绘制三个圆型图  
cluster0 = [dict(type='circle',  
                 xref='x', yref='y',  
                 x0=min(x0), y0=min(y0),  
                 x1=max(x0), y1=max(y0),  
                 opacity=.25,  
                 line=dict(color='#835AF1'),  
                 fillcolor='#835AF1')]  
cluster1 = [dict(type='circle',  
                 xref='x', yref='y',  
                 x0=min(x1), y0=min(y1),  
                 x1=max(x1), y1=max(y1),  
                 opacity=.25,  
                 line=dict(color='#7FA6EE'),  
                 fillcolor='#7FA6EE')]  
cluster2 = [dict(type='circle',  
                 xref='x', yref='y',  
                 x0=min(x2), y0=min(y2),  
                 x1=max(x2), y1=max(y2),  
                 opacity=.25,  
                 line=dict(color='#B8F7D4'),  
                 fillcolor='#B8F7D4')]  
  
# 将所有的散点图和圆型图放在一个Figure对象中  
fig = go.Figure(data + cluster0 + cluster1 + cluster2)  
  
# 设置一个按钮来控制所有的图表  
fig.update_layout(updatemenus=[dict(type="buttons", buttons=[dict(label="Play", method="animate", args=[None])])])

结合GPT给出回答如下请题主参考
要实现多个html合并后共享或联动按钮,可以使用Plotly Dash来实现。Plotly Dash是一个Python框架,用于创建交互式Web应用程序,它具有直观的用户界面和交互式数据可视化。

以下是使用Plotly Dash实现多个html合并后共享或联动按钮的步骤:

  1. 安装Plotly Dash:使用pip install dash命令安装Plotly Dash库。

  2. 导入所需的库和模块:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.express as px
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import pandas as pd
  1. 定义一个函数,用于生成html图表页面:
def generate_html_chart(id, fig, title):
    return html.Div(
        [
            dcc.Graph(id=id, figure=fig),
            html.Br(),
            html.Button('点击我', id=f'{id}_button'),
            html.Hr(),
            html.H2(title)
        ]
    )

该函数使用dcc.Graph创建一个Plotly图表,并使用html.Button创建一个控制图表的按钮。

  1. 定义应用程序:
app = dash.Dash(__name__)

# 创建多个图表
df = pd.read_csv('data.csv')

fig1 = px.scatter(df, x='x1', y='y1')
fig2 = make_subplots(rows=2, cols=1)
fig2.add_trace(go.Scatter(x=df['x2'], y=df['y2']), row=1, col=1)
fig2.add_trace(go.Scatter(x=df['x3'], y=df['y3']), row=2, col=1)

# 定义应用程序布局
app.layout = html.Div(
    [
        generate_html_chart('chart1', fig1, '图表1'),
        generate_html_chart('chart2', fig2, '图表2'),
    ]
)

# 定义回调函数
@app.callback(
    Output('chart1', 'figure'),
    Input('chart1_button', 'n_clicks')
)
def update_chart1(n_clicks):
    if n_clicks is None:
        return dash.no_update

    # 更新图表数据或布局
    # ...

    return fig1

@app.callback(
    Output('chart2', 'figure'),
    Input('chart2_button', 'n_clicks')
)
def update_chart2(n_clicks):
    if n_clicks is None:
        return dash.no_update

    # 更新图表数据或布局
    # ...

    return fig2
  1. 运行应用程序:
if __name__ == '__main__':
    app.run_server(debug=True)

该应用程序创建两个图表,每个图表都有一个控制按钮。当用户单击按钮时,应用程序会调用相应的回调函数来更新图表数据或布局。

要实现共享或联动按钮,在回调函数中添加修改其他图表的代码即可。例如,要将“点击我”按钮更改为“已单击”:

@app.callback(
    Output('chart1_button', 'children'),
    Input('chart2_button', 'n_clicks')
)
def update_chart1_button(n_clicks):
    if n_clicks:
        return '已单击'

    return '点击我'

此回调函数将chart2按钮的单击次数作为输入,并将chart1按钮的文本作为输出。当chart2按钮被单击时,chart1按钮的文本将更改为“已单击”。

这样就实现了多个html合并后共享或联动按钮的效果。

引用 皆我百晓生 小程序回复内容作答:

根据我的了解,teigha.net 4.0 是希望提供面向 CAD/ CAM/ GIS 应用程序的一揽子解决方案,包括绘图、放样、交集、并集等功能。因此,理论上来说是可以实现放样、交集和并集操作的。

要实现这些功能,可以使用teigha.net的API和类库进行操作。teigha.net提供了一系列的类和方法,可以通过这些API实现对象间的几何操作。例如,可以使用Intersection方法实现两个几何对象的交集操作,使用Union方法实现并集操作。

具体的实现方法可能因使用的编程语言和具体的场景而有所不同,但一般的步骤如下:

1.导入teigha.net库。首先,在你的项目中添加teigha.net类库的引用,并在代码中导入相应的命名空间。

2.创建几何对象。使用teigha.net的类来创建需要进行操作的几何对象,如点、线、多边形等。

3.执行相应的操作。根据需求执行相应的放样、交集、并集等操作,使用合适的方法来实现。

4.获取结果。根据操作的不同,可以通过输出参数、返回值或其他方式来获取操作的结果。

需要注意的是,具体的实现方法可能会因teigha.net的版本和更新而有所不同。因此,在实际应用中,建议参考teigha.net的官方文档和示例代码来实现相应的功能。