3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

uvでプロジェクト管理して、ReflexでPlotlyグラフアプリをつくる

Posted at

最近、個人的に大注目のuvとReflexを紹介します。

uv

uvはPythonのプロジェクトを管理するツールです。これまで似たようなツールで、pipenv、venvを使ってきましたが、uvは一番使い心地がよく気に入っています。

Pythonのバージョン管理もできるし、ライブラリのインストールは早いし、アプリの実行のために仮想環境に入らなくてもいいしで、いいことづくめです。

Reflex

ReflexはwebアプリをPythonだけで作れる、React(JavaScript)のようなライブラリです。(実際にReactコードに変換しています)
webアプリのパーツとその状態をモジュール化できます。Pythonistのみなさんも、Pythonの関数を作るようにパーツを作って、パーツを組み合わせることでwebアプリを簡単に作れるのではないでしょうか。

今のところホットリロードが少し遅かったり、Windowsでは謎フリーズが起こったりと、フラストレーションがたまることもありますが、コンセプトは非常に面白いので今後流行っていくんじゃないかなと思っています。

グラフアプリ製作

今回はuvを使ってReflexプロジェクトを作成し、簡単なグラフアプリを作ってみたいと思います。
作るものは以下のような、ボタンを押すとYの値がランダムに変わるだけのアプリです。

Screen recording 2024-11-01 23.34.48.gif

あらかじめuvだけは公式サイトを見てインストールしておいてください。

まずはuvでプロジェクトを作って、プロジェクトのディレクトリに入ります。ついでに不要なhello.pyも削除しておきましょう。

uv init my-awesome-app
cd my-awesome-app/
rm hello.py

次にReflexをプロジェクトにインストールします。uvのおかげで、インストールがすごく早いです。

uv add reflex

インストールしたReflexのコマンドラインツールを使って、プロジェクトを初期化します。仮想環境をアクティブにしなくても、uvコマンドを使えばプロジェクト内にインストールされたツールを直接実行できます。

uv run reflex init

使用するテンプレートを聞かれるので、とりあえず今回は0(blank)を選んで実行しましょう。
この時点ですでにwebアプリができているので、一度動作確認をします。

uv run reflex run

すると、初回は必要なパッケージなどがインストールされるため少し時間がかかりますが、webアプリが起動します。
手元のパソコンで実行しているなら、http://localhost:3000 にアクセスするとアプリが確認できるはずです。

これだけで十分にuvとReflexの魅力は伝わったかもしれませんが、最後にPlotlyを使ったグラフアプリを作ります。
Reflexはデフォルト状態でPlotlyの描画パーツを使えますが、plotlyの関数は使えないので、uvでplotlyをインストールします。

uv add plotly

そして、my_awesome_app/my_awesome_app.pyを以下のように修正します。

import random

import reflex as rx
import plotly.graph_objects as go


class State(rx.State):
    """The app state."""
    x: list[int] = [1, 2, 3, 4, 5]
    y: list[float] = [random.random() for _ in range(5)]
    fig: go.Figure = go.Figure(
            data=go.Scatter(
                x=x,
                y=y,
                mode='markers',
                )
            )

    def change_y(self) -> None:
        self.y = [random.random() for _ in range(5)]
        self.fig = go.Figure(
                data=go.Scatter(
                    x=self.x,
                    y=self.y,
                    mode='markers',
                    )
                )


def index() -> rx.Component:
    return rx.container(
        rx.vstack(
            rx.plotly(data=State.fig),
            rx.button(
                "Change Values",
                on_click=State.change_y,
                ),
            justify="center",
            align='center',
            min_height="85vh",
        ),
    )


app = rx.App()
app.add_page(index)

注意点としては、ライブラリをつかった複雑な計算などは、rx.Stateを継承したクラス内のメソッド(今回はchange_y)に書くこと。計算した結果は、クラス変数 State.figに入れて、グラフ描画用のパーツ(rx.plotly)の引数dataに渡すことで、ユーザーが見えるような状態になります。

あとはReactのように、パーツ内の引数でレイアウトを整えて完了です。

ホットリロードがうまくいかないようでしたら、ctrl-Cで一度停止して、再度

uv run reflex run

を実行しましょう。Reflexが必要なツールを自動でインストールして、サーバーが起動します。


いかがでしたか。興味がわいた方がいらっしゃったら嬉しいです。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?