こんにちは、JS2IIUです。
Streamlitには多くのUI要素が準備されており、基本的なことはカバーされています。少し高度なコンポーネントを使いたい場合にはBootstrapなどのフロントエンドフレームワークを活用すると洗練された見た目を実現できます。今回もよろしくお願いします。
はじめに
Streamlitは、PythonでデータサイエンスのWebアプリケーションを簡単に構築できるフレームワークです。しかし、デフォルトのスタイルだけでは、より洗練されたUIを作成するのに限界があります。そこで今回は、StreamlitにBootstrapのCardコンポーネントを組み込む方法を詳しく解説します。
Bootstrapとは?
Bootstrapは、世界で最も人気のあるフロントエンドフレームワークの一つです。Twitterによって開発され、現在はオープンソースプロジェクトとして維持されています。
Bootstrapの主な特徴
- レスポンシブデザイン: モバイル、タブレット、デスクトップに対応
- 豊富なコンポーネント: ボタン、カード、ナビゲーションバーなど
- グリッドシステム: 12列のグリッドレイアウト
- カスタマイズ可能: SassやCSSでスタイルを調整可能
- 軽量: 必要な機能のみを選択して使用可能
StreamlitとBootstrapの組み合わせ
メリット
- デザインの向上: Streamlitのデフォルトスタイルより美しいUIを作成
- 一貫性: 業界標準のデザインパターンを使用
- レスポンシブ対応: 自動的にモバイル対応
- 開発効率: 既存のBootstrapコンポーネントを活用
- カスタマイズ性: CSSで細かいスタイル調整が可能
デメリット
- 学習コスト: Bootstrap とHTMLの知識が必要
- Streamlitの制約: 一部のBootstrap機能が制限される可能性
- 保守性: HTMLとPythonコードの混在により複雑化
- パフォーマンス: 追加のCSSとJavaScriptの読み込みが必要
- 互換性: Streamlitのアップデートで動作しなくなる可能性
実装コードの解説
今回のサンプルコードを詳しく見ていきましょう。全体を一つに繋げたコードは下の方にあります。

1. 初期設定
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の読み込み
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. データの定義
cards_data = [
{
"title": "Card 1",
"text": "これは最初のカードです。Bootstrapのカードコンポーネントを使用しています。",
"image": "https://placehold.jp/3d4070/ffffff/300x200.png?text=Cards_1"
},
# ... 他のカード
]カードの内容を辞書のリストとして定義しています。この構造により、動的にカードを生成できます。
4. HTMLの生成
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>
"""この部分では、以下の重要な要素を使用しています:
- Flexboxレイアウト:
display: flexとflex-wrap: wrapでカードを柔軟に配置 - Bootstrap Cardクラス:
.card、.card-img-top、.card-bodyなどの標準クラス - 日本語フォント: Noto Sans JPを指定して日本語表示を改善
5. コンポーネントの表示
components.html(cards_html, height=800)components.html()を使用してHTMLコンテンツを表示します。heightパラメータでコンテナの高さを指定しています。
6. スタイルの追加
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でホバーエフェクトや画像の表示を調整しています。
コード全体
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. データ可視化ダッシュボード
# 売上データのカード表示
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. 機械学習モデルの結果表示
# モデルの精度をカードで表示
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の選択
# より高速な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. 必要な機能のみ使用
# 必要な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)トラブルシューティング
よくある問題と解決策
- スタイルが適用されない
unsafe_allow_html=Trueを確認- CSSの読み込み順序を確認
- レスポンシブが機能しない
- viewport meta tagの追加
- 適切なBreakpointクラスの使用
- 日本語フォントが表示されない
- Google Fontsの読み込み確認
- フォールバックフォントの指定
まとめ
StreamlitとBootstrapを組み合わせることで、データサイエンスのWebアプリケーションをより魅力的にできます。ただし、学習コストや保守性を考慮して、プロジェクトの要件に応じて適切に使用することが重要です。
今回のサンプルコードを参考に、あなたのStreamlitアプリケーションをより美しく、使いやすくしてみてください。
参考
最後まで読んでいただきありがとうございます。
ご意見、ご感想はコメント欄までお願い致します。


コメント