acc_layout



```python
import json
import streamlit as st
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from PIL import Image
import numpy as np

def save_to_json(df, file_path):
    df.to_json(file_path, orient='records', lines=True)

def main():
    # ページ設定
    st.set_page_config(layout="wide")
    st.title("Image Annotation with Dataframe Points")


    col1, col2 = st.columns([2, 1])

    with col1:

        # データフレームの初期化
        df = pd.DataFrame(
            [
                {'ID': '1', "x": 123, "y": 32, "sin": True, "aco": True, "shock": True, 'X-axis':True, 'Y-axis':True, 'Z-axis':True, "comment": ''},
                {'ID': '2', "x": 334, "y": 124, "sin": False, "aco": True, "shock": True,'X-axis':True, 'Y-axis':True, 'Z-axis':True, "comment": ''},
                {'ID': '3', "x": 323, "y": 234, "sin": True, "aco": True, "shock": True, 'X-axis':True, 'Y-axis':True, 'Z-axis':True,"comment": ''},
            ]
        )

        # ポップオーバー風の入力フォーム
        with st.popover("新しい加速度計を追加"):
            new_id = st.text_input('Enter new ID')
            if st.button('Add row'):
                if new_id:
                    new_row = pd.DataFrame([{
                        'ID': new_id, "x": 0, "y": 0, "sin": False, "aco": False, "shock": False,
                        'X-axis': False, 'Y-axis': False, 'Z-axis': False, "comment": ''
                    }])
                    df = pd.concat([df, new_row], ignore_index=True)
                else:
                    st.warning('ID cannot be empty!')


        # Streamlitのデータエディタを使ってデータフレームを編集
        edited_df = st.data_editor(df, num_rows="dynamic")

    with col2:
        comp_list = ['comp1', 'comp2', 'comp3']
        acc_list = ['acc1', 'acc2', 'acc3'] #いずれは自動取得したい
        acc_list = list(edited_df['ID'])

        # メイン処理=============================================================================================================
        # accの数だけマルチセレクトboxを作成
        for acc_name in acc_list:
            st.multiselect(acc_name, options=comp_list)


    # ローカルファイルから画像を読み込む
    img_path = "aaaa_plot.png"  # ここに画像ファイルのパスを指定します
    img = Image.open(img_path)

    # 画像をPlotlyに適した配列形式に変換する
    img_array = np.array(img)

    # 画像をプロット
    fig = px.imshow(img_array)
    
    # 編集後のデータフレームのx, yの位置に点を打つ
    for index, row in edited_df.iterrows():
        # チェックが付いているカラム名を取得
        checked_columns = [col for col in ['sin', 'aco', 'shock'] if row[col]]
        # IDとチェックが付いたカラム名を表示する文字列を生成
        label = f"{row['ID']}, " + ", ".join(checked_columns)
        
        fig.add_trace(go.Scatter(
            x=[row['x']],
            y=[row['y']],
            mode='markers',
            marker=dict(color='red', size=10),
            text=label,
            name=f'Point {index+1}'
        ))

        fig.add_annotation(
            x=row['x'],
            y=row['y']+30,
            text=label,
            showarrow=False,
            font=dict(size=10, color='red')
        )

        # "aco"がTrueの場合、水平矢印を追加
        if row['X-axis']:
            fig.add_annotation(
                x=row['x'] + 100,  # 矢印の終点を設定
                y=row['y'],
                ax=row['x'],  # 矢印の原点を点に設定
                ay=row['y'],
                xref="x",
                yref="y",
                axref="x",
                ayref="y",
                showarrow=True,
                arrowhead=2,
                arrowsize=1,
                arrowwidth=2,
                arrowcolor="blue"
            )

        # "sin"がTrueの場合、垂直矢印を追加
        if row['Y-axis']:
            fig.add_annotation(
                x=row['x'],
                y=row['y'] - 100,  # 矢印の終点を設定
                ax=row['x'],
                ay=row['y'] + 20,  # 矢印の原点を点に設定
                xref="x",
                yref="y",
                axref="x",
                ayref="y",
                showarrow=True,
                arrowhead=2,
                arrowsize=1,
                arrowwidth=2,
                arrowcolor="green"
            )



    fig.update_layout(
        hovermode='closest',
        showlegend=False
    )

    st.plotly_chart(fig)

    # 保存ボタンを追加
    if st.button("Save Changes"):
        file_path = 'edited_data.json'
        save_to_json(edited_df, file_path)
        st.success(f"Changes saved to {file_path}")

if __name__ == '__main__':
    main()

```