サイトアイコン アマチュア無線局JS2IIU

【Streamlit】BootstrapのCardsを使う方法

BootstrapのCardsを表示する

こんにちは、JS2IIUです。
Streamlitには多くのUI要素が準備されており、基本的なことはカバーされています。少し高度なコンポーネントを使いたい場合にはBootstrapなどのフロントエンドフレームワークを活用すると洗練された見た目を実現できます。今回もよろしくお願いします。

はじめに

Streamlitは、PythonでデータサイエンスのWebアプリケーションを簡単に構築できるフレームワークです。しかし、デフォルトのスタイルだけでは、より洗練されたUIを作成するのに限界があります。そこで今回は、StreamlitにBootstrapのCardコンポーネントを組み込む方法を詳しく解説します。

Bootstrapとは?

Bootstrapは、世界で最も人気のあるフロントエンドフレームワークの一つです。Twitterによって開発され、現在はオープンソースプロジェクトとして維持されています。

Bootstrapの主な特徴

StreamlitとBootstrapの組み合わせ

メリット

  1. デザインの向上: Streamlitのデフォルトスタイルより美しいUIを作成
  2. 一貫性: 業界標準のデザインパターンを使用
  3. レスポンシブ対応: 自動的にモバイル対応
  4. 開発効率: 既存のBootstrapコンポーネントを活用
  5. カスタマイズ性: CSSで細かいスタイル調整が可能

デメリット

  1. 学習コスト: Bootstrap とHTMLの知識が必要
  2. Streamlitの制約: 一部のBootstrap機能が制限される可能性
  3. 保守性: HTMLとPythonコードの混在により複雑化
  4. パフォーマンス: 追加のCSSとJavaScriptの読み込みが必要
  5. 互換性: Streamlitのアップデートで動作しなくなる可能性

実装コードの解説

今回のサンプルコードを詳しく見ていきましょう。全体を一つに繋げたコードは下の方にあります。

1. 初期設定

Python
import streamlit as st
import streamlit.components.v1 as components

# ページの設定
st.set_page_config(page_title="Bootstrap Cards Demo", layout="wide")

streamlit.components.v1はHTMLコンポーネントを表示するために必要です。layout="wide"でページ幅を広げることで、カードのレイアウトがより見やすくなります。

2. Bootstrap CDNの読み込み

Python
st.markdown("""
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
""", unsafe_allow_html=True)

Bootstrap 5.1.3をCDNから読み込んでいます。unsafe_allow_html=Trueを使用することで、HTMLタグを有効にできます。

3. データの定義

Python
cards_data = [
    {
        "title": "Card 1",
        "text": "これは最初のカードです。Bootstrapのカードコンポーネントを使用しています。",
        "image": "https://placehold.jp/3d4070/ffffff/300x200.png?text=Cards_1"
    },
    # ... 他のカード
]

カードの内容を辞書のリストとして定義しています。この構造により、動的にカードを生成できます。

4. HTMLの生成

Python
cards_html = """
<div style="display: flex; flex-wrap: wrap; gap: 24px; justify-content: center;">
"""

for card in cards_data:
    cards_html += f"""
    <div class="card" style="width: 20rem; margin-bottom: 24px; font-family: 'Noto Sans JP', 'Noto Sans', 'Meiryo', sans-serif;">
        <img src="{card['image']}" class="card-img-top" alt="{card['title']}">
        <div class="card-body">
            <h5 class="card-title">{card['title']}</h5>
            <p class="card-text">{card['text']}</p>
            <a href="#" class="btn btn-primary">詳細を見る</a>
        </div>
    </div>
    """

この部分では、以下の重要な要素を使用しています:

5. コンポーネントの表示

Python
components.html(cards_html, height=800)

components.html()を使用してHTMLコンテンツを表示します。heightパラメータでコンテナの高さを指定しています。

6. スタイルの追加

Python
st.markdown("""
<style>
    @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap');
    .card {
        transition: transform 0.2s;
        font-family: 'Noto Sans JP', 'Noto Sans', 'Meiryo', sans-serif !important;
    }
    .card:hover {
        transform: translateY(-5px);
    }
    .card-img-top {
        height: 200px;
        object-fit: cover;
    }
</style>
""", unsafe_allow_html=True)

カスタムCSSでホバーエフェクトや画像の表示を調整しています。

コード全体

Python
import streamlit as st
import streamlit.components.v1 as components

# ページの設定
st.set_page_config(page_title="Bootstrap Cards Demo", layout="wide")

# Bootstrap CSSを読み込み
st.markdown("""
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
""", unsafe_allow_html=True)

# タイトル
st.title("Bootstrap Cards Demo")

# カードのデータ
cards_data = [
    {
        "title": "Card 1",
        "text": "これは最初のカードです。Bootstrapのカードコンポーネントを使用しています。",
        "image": "https://placehold.jp/3d4070/ffffff/300x200.png?text=Cards_1"
    },
    {
        "title": "Card 2", 
        "text": "これは2番目のカードです。プレースホルダー画像を使用しています。",
        "image": "https://placehold.jp/3d4070/ffffff/300x200.png?text=Cards_2"
    },
    {
        "title": "Card 3",
        "text": "これは3番目のカードです。レスポンシブなデザインになっています。",
        "image": "https://placehold.jp/3d4070/ffffff/300x200.png?text=Cards_3"
    },
    {
        "title": "Card 4",
        "text": "これは4番目のカードです。Bootstrapのグリッドシステムを使用しています。",
        "image": "https://placehold.jp/3d4070/ffffff/300x200.png?text=Cards_4"
    },
    {
        "title": "Card 5",
        "text": "これは5番目のカードです。カードの高さは自動的に調整されます。",
        "image": "https://placehold.jp/3d4070/ffffff/300x200.png?text=Cards_5"
    },
    {
        "title": "Card 6",
        "text": "これは6番目のカードです。最後の行の最後のカードです。",
        "image": "https://placehold.jp/3d4070/ffffff/300x200.png?text=Cards_6"
    }
]

# Bootstrap Cardsを2行3列で配置
cards_html = """
<div style="display: flex; flex-wrap: wrap; gap: 24px; justify-content: center;">
"""
for card in cards_data:
    cards_html += f"""
    <div class=\"card\" style=\"width: 20rem; margin-bottom: 24px; font-family: 'Noto Sans JP', 'Noto Sans', 'Meiryo', sans-serif;\">
        <img src=\"{card['image']}\" class=\"card-img-top\" alt=\"{card['title']}\">
        <div class=\"card-body\">
            <h5 class=\"card-title\">{card['title']}</h5>
            <p class=\"card-text\">{card['text']}</p>
            <a href=\"#\" class=\"btn btn-primary\">詳細を見る</a>
        </div>
    </div>
    """
cards_html += """
</div>
"""

# HTMLを表示
components.html(cards_html, height=800)

# 追加のスタイル
st.markdown("""
<style>
    @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;700&display=swap');
    .card {
        transition: transform 0.2s;
        font-family: 'Noto Sans JP', 'Noto Sans', 'Meiryo', sans-serif !important;
    }
    .card:hover {
        transform: translateY(-5px);
    }
    .card-img-top {
        height: 200px;
        object-fit: cover;
    }
</style>
""", unsafe_allow_html=True)

# Bootstrap JavaScriptを読み込み(必要に応じて)
st.markdown("""
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
""", unsafe_allow_html=True)

実践的な活用例

活用事例をいくつか挙げます。メインの部分のみコードを示します。Cardsはカタログのようなデータを視覚的にわかりやすく表示することが可能です。

1. データ可視化ダッシュボード

Python
# 売上データのカード表示
for product in products:
    card_html = f"""
    <div class="card">
        <div class="card-body">
            <h5 class="card-title">{product['name']}</h5>
            <p class="card-text">売上: ¥{product['sales']:,}</p>
            <div class="progress">
                <div class="progress-bar" style="width: {product['progress']}%"></div>
            </div>
        </div>
    </div>
    """

2. 機械学習モデルの結果表示

Python
# モデルの精度をカードで表示
for model in models:
    card_html = f"""
    <div class="card">
        <div class="card-body">
            <h5 class="card-title">{model['name']}</h5>
            <p class="card-text">精度: {model['accuracy']:.2%}</p>
            <span class="badge bg-{'success' if model['accuracy'] > 0.8 else 'warning'}">
                {'Good' if model['accuracy'] > 0.8 else 'Needs Improvement'}
            </span>
        </div>
    </div>
    """

パフォーマンスの最適化

1. CDNの選択

Python
# より高速なCDN
st.markdown("""
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
""", unsafe_allow_html=True)

2. 必要な機能のみ使用

Python
# 必要なBootstrapコンポーネントのみ読み込み
st.markdown("""
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap-grid.min.css" rel="stylesheet">
""", unsafe_allow_html=True)

トラブルシューティング

よくある問題と解決策

まとめ

StreamlitとBootstrapを組み合わせることで、データサイエンスのWebアプリケーションをより魅力的にできます。ただし、学習コストや保守性を考慮して、プロジェクトの要件に応じて適切に使用することが重要です。

今回のサンプルコードを参考に、あなたのStreamlitアプリケーションをより美しく、使いやすくしてみてください。

参考

最後まで読んでいただきありがとうございます。
ご意見、ご感想はコメント欄までお願い致します。

モバイルバージョンを終了