カテゴリー

Pythonでの比較

【plotly&ボタンとスライダー】goとpxでのupdatemenusとsliders

2021年10月31日

こんな人にオススメ

plotlyってgopxがあるけど、それぞれでボタン・スライダーを作成するのはどうしたらいいの?

書き方とかって異なる?

ということで、今回はplotlygoplotly.graph_objects)とpxplotly.express)でボタンつき、スライダーつきのグラフを作成する。

go, pxそれぞれでグラフを描く方法は異なるけど、ボタンについてはかなり似ている。スライダーはかなり異なる。

python環境は以下。

  • Python 3.9.7
  • pandas 1.3.3
  • numpy 1.21.2
  • plotly 5.3.1
  • plotly-orca 3.4.2

運営者のメガネです。YouTubeTwitterInstagram、自己紹介はこちら、お問い合わせはこちらから。

運営者メガネ

作成したコード全文

下準備

import numpy as np
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
import plotly.io as pio

まずは下準備のimport関連。今回は自作テンプレートは使用しない。シンプルにデフォルトのグラフを作成する。

【随時更新 備忘録】plotlyのグラフ即席作成コード

続きを見る

使用するデータ

# 横軸は-2から+2までを0.1刻み
x = np.arange(-2, 2 + 0.1, 0.1)
print(x)
# [-2.00000000e+00 -1.90000000e+00 -1.80000000e+00 -1.70000000e+00
#  -1.60000000e+00 -1.50000000e+00 -1.40000000e+00 -1.30000000e+00
#  -1.20000000e+00 -1.10000000e+00 -1.00000000e+00 -9.00000000e-01
#  -8.00000000e-01 -7.00000000e-01 -6.00000000e-01 -5.00000000e-01
#  -4.00000000e-01 -3.00000000e-01 -2.00000000e-01 -1.00000000e-01
#   1.77635684e-15  1.00000000e-01  2.00000000e-01  3.00000000e-01
#   4.00000000e-01  5.00000000e-01  6.00000000e-01  7.00000000e-01
#   8.00000000e-01  9.00000000e-01  1.00000000e+00  1.10000000e+00
#   1.20000000e+00  1.30000000e+00  1.40000000e+00  1.50000000e+00
#   1.60000000e+00  1.70000000e+00  1.80000000e+00  1.90000000e+00
#   2.00000000e+00]

今回使用するデータは-2から2までを0.1刻みにした配列を横軸に、この横軸を1から5次関数として計算した配列を縦軸とする。

各○次関数はどのデータかがわかりやすいようにdictに格納しておく。これで配列にラベルをつけることができる。

# 縦軸は1次関数から5次関数まで
data = {}
for order in range(1, 6):
    data[f"order{order}"] = x ** order
print(data)
# {'order1': array([-2.00000000e+00, -1.90000000e+00, -1.80000000e+00, -1.70000000e+00,
#        -1.60000000e+00, -1.50000000e+00, -1.40000000e+00, -1.30000000e+00,
#        -1.20000000e+00, -1.10000000e+00, -1.00000000e+00, -9.00000000e-01,
#        -8.00000000e-01, -7.00000000e-01, -6.00000000e-01, -5.00000000e-01,
#        -4.00000000e-01, -3.00000000e-01, -2.00000000e-01, -1.00000000e-01,
#         1.77635684e-15,  1.00000000e-01,  2.00000000e-01,  3.00000000e-01,
#         4.00000000e-01,  5.00000000e-01,  6.00000000e-01,  7.00000000e-01,
#         8.00000000e-01,  9.00000000e-01,  1.00000000e+00,  1.10000000e+00,
#         1.20000000e+00,  1.30000000e+00,  1.40000000e+00,  1.50000000e+00,
#         1.60000000e+00,  1.70000000e+00,  1.80000000e+00,  1.90000000e+00,
#         2.00000000e+00]), 'order2': array([4.00000000e+00, 3.61000000e+00, 3.24000000e+00, 2.89000000e+00,
#        2.56000000e+00, 2.25000000e+00, 1.96000000e+00, 1.69000000e+00,
#        1.44000000e+00, 1.21000000e+00, 1.00000000e+00, 8.10000000e-01,
#        6.40000000e-01, 4.90000000e-01, 3.60000000e-01, 2.50000000e-01,
#        1.60000000e-01, 9.00000000e-02, 4.00000000e-02, 1.00000000e-02,
#        3.15544362e-30, 1.00000000e-02, 4.00000000e-02, 9.00000000e-02,
#        1.60000000e-01, 2.50000000e-01, 3.60000000e-01, 4.90000000e-01,
#        6.40000000e-01, 8.10000000e-01, 1.00000000e+00, 1.21000000e+00,
#        1.44000000e+00, 1.69000000e+00, 1.96000000e+00, 2.25000000e+00,
#        2.56000000e+00, 2.89000000e+00, 3.24000000e+00, 3.61000000e+00,
#        4.00000000e+00]), 'order3': array([-8.00000000e+00, -6.85900000e+00, -5.83200000e+00, -4.91300000e+00,
#        -4.09600000e+00, -3.37500000e+00, -2.74400000e+00, -2.19700000e+00,
#        -1.72800000e+00, -1.33100000e+00, -1.00000000e+00, -7.29000000e-01,
#        -5.12000000e-01, -3.43000000e-01, -2.16000000e-01, -1.25000000e-01,
#        -6.40000000e-02, -2.70000000e-02, -8.00000000e-03, -1.00000000e-03,
#         5.60519386e-45,  1.00000000e-03,  8.00000000e-03,  2.70000000e-02,
#         6.40000000e-02,  1.25000000e-01,  2.16000000e-01,  3.43000000e-01,
#         5.12000000e-01,  7.29000000e-01,  1.00000000e+00,  1.33100000e+00,
#         1.72800000e+00,  2.19700000e+00,  2.74400000e+00,  3.37500000e+00,
#         4.09600000e+00,  4.91300000e+00,  5.83200000e+00,  6.85900000e+00,
#         8.00000000e+00]), 'order4': array([1.60000000e+01, 1.30321000e+01, 1.04976000e+01, 8.35210000e+00,
#        6.55360000e+00, 5.06250000e+00, 3.84160000e+00, 2.85610000e+00,
#        2.07360000e+00, 1.46410000e+00, 1.00000000e+00, 6.56100000e-01,
#        4.09600000e-01, 2.40100000e-01, 1.29600000e-01, 6.25000000e-02,
#        2.56000000e-02, 8.10000000e-03, 1.60000000e-03, 1.00000000e-04,
#        9.95682444e-60, 1.00000000e-04, 1.60000000e-03, 8.10000000e-03,
#        2.56000000e-02, 6.25000000e-02, 1.29600000e-01, 2.40100000e-01,
#        4.09600000e-01, 6.56100000e-01, 1.00000000e+00, 1.46410000e+00,
#        2.07360000e+00, 2.85610000e+00, 3.84160000e+00, 5.06250000e+00,
#        6.55360000e+00, 8.35210000e+00, 1.04976000e+01, 1.30321000e+01,
#        1.60000000e+01]), 'order5': array([-3.20000000e+01, -2.47609900e+01, -1.88956800e+01, -1.41985700e+01,
#        -1.04857600e+01, -7.59375000e+00, -5.37824000e+00, -3.71293000e+00,
#        -2.48832000e+00, -1.61051000e+00, -1.00000000e+00, -5.90490000e-01,
#        -3.27680000e-01, -1.68070000e-01, -7.77600000e-02, -3.12500000e-02,
#        -1.02400000e-02, -2.43000000e-03, -3.20000000e-04, -1.00000000e-05,
#         1.76868732e-74,  1.00000000e-05,  3.20000000e-04,  2.43000000e-03,
#         1.02400000e-02,  3.12500000e-02,  7.77600000e-02,  1.68070000e-01,
#         3.27680000e-01,  5.90490000e-01,  1.00000000e+00,  1.61051000e+00,
#         2.48832000e+00,  3.71293000e+00,  5.37824000e+00,  7.59375000e+00,
#         1.04857600e+01,  1.41985700e+01,  1.88956800e+01,  2.47609900e+01,
#         3.20000000e+01])}

このdictデータでgoのプロットはできるが、pxについてはこのままだと使いにくいのでpandasのデータフレームに変換しておく。

px用にデータフレームに変換

px_data = {'x': x.tolist() * len(data)}  # データをまとめる用のdict
px_y = []  # px用のyの値
order = []  # px用のオーダーの値
# 各データごとにdictに格納
for num, val in enumerate(data.values(), 1):
    px_y.append(val.tolist())  # listに変換して後から展開
    order.append([f"{num}"] * len(val))  # 各データの数だけオーダーの値も複製

データフレームの列は横軸のx、縦軸のy、そして各次数のorderを名称とする。orderは1次関数のデータが続いている間はずっと1を示し続ける。

orderを設定しておくことで、どこまでが1次関数なのかというような判断が可能となる。ただし、orderは文字列ではなく数値にしておくと、凡例作成時に自動でカラーバーができてしまうので注意。

また、上のコードだとpx_yorderはそれぞれ2次元配列になっている。

# 現状だと2次元配列になっているから展開して1次元配列に
print(order)
# [['1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1'], ['2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2'], ['3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3'], ['4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4'], ['5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5']]

なので1次元配列に変換する。そうしないとデータフレームにするのが面倒になる。

px_y = sum(px_y, [])  # yの値を展開
order = sum(order, [])  # オーダーの値を展開
print(order)
# ['1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', '5']

あとはできたデータをdictに入れてからデータフレームに変換。これでpx用のデータフレームが完成。

# データをdictに入れる
px_data['y'] = px_y
px_data['order'] = order
# データフレームに変換
df = pd.DataFrame(px_data)
print(df)
#        x         y order
# 0   -2.0  -2.00000     1
# 1   -1.9  -1.90000     1
# 2   -1.8  -1.80000     1
# 3   -1.7  -1.70000     1
# 4   -1.6  -1.60000     1
# ..   ...       ...   ...
# 200  1.6  10.48576     5
# 201  1.7  14.19857     5
# 202  1.8  18.89568     5
# 203  1.9  24.76099     5
# 204  2.0  32.00000     5

# [205 rows x 3 columns]

諸関数の定義

ここではグラフ作成に使用する関数を定義する。以下の2つを定義する。

  1. ボタン・スライダーの内容作成の関数
  2. グラフ保存用の関数

ボタン・スライダーの内容作成の関数

# ボタン・スライダー作成
def set_menus():
    # ボタン・スライダーの内容を作成
    length = len(data)
    # ボタン・スライダーは全プロット表示と各プロット表示で2つに分けて作成

    # 全プロット表示用のボタン・スライダー作成
    visible = [True] * length
    menu = dict(
        label='All', method='update',
        args=[dict(visible=visible), dict(title='All')]
    )
    menus = [menu]  # ボタン・スライダー全体の設定のlistに格納

    # 各プロットのみを表示するためのボタン・スライダー作成
    for num, order in enumerate(data):
        # 一旦全てのプロットを非表示に
        visible = [False] * length
        # 該当するボタン・スライダーのプロット部分だけ表示にして、ラベルを作成
        visible[num] = True

        menu = dict(
            label=order, method='update',
            args=[dict(visible=visible), dict(title=order)]
        )
        menus.append(menu)

    return menus

設定内容としてはボタンもスライダーも共通。以下の2条件を満たせばいい。

  1. 全プロット表示
  2. 各プロット表示、その他のプロットは非表示

ボタンやスライダーについて詳しくは以下を参照してほしいが、今回だとvisibleで指定したboolTrueだと表示、Falseだと非表示。

【plotly&ボタン】plotlyのupdatemenusにbuttonsを追加

続きを見る

【plotly&スライダー】plotlyのslidersにスライダーを追加

続きを見る

また、argsの初めのdictがプロットに関する内容、2つ目のdictがレイアウトに関する内容を示している。ここを逆にしてもエラーとはならず何も起きないだけ。

グラフ保存用の関数

# グラフ保存用の関数
def save(fig, config, save_name):
    pio.orca.config.executable = '/Applications/orca.app/Contents/MacOS/orca'
    pio.write_html(fig, f"{save_name}.html", config=config,)
    pio.write_image(fig, f"{save_name}.png")

グラフの保存形式はhtmlとpngにした。plotlyのグラフ保存については以下で解説している。

plotlyでグラフを静止画として保存する際に出るポップアップ
【plotly&orca】plotlyで静止画保存(orca)

続きを見る

また、configはグラフ右上のツールバーだが、今回はごちゃごちゃするのでNoneと指定して無効にする。

ボタンとスライダー設定

set_menus関数でボタン・スライダーの内容の設定はできるので、ここではこれらの設定をグラフに反映させる設定を行う。

ボタン(updatemenus)とスライダー(sliders)では引数が異なるのでここでは分けて考えることにする。

ボタンの設定

updatemenus = [
    dict(
        active=0, buttons=set_menus(), type='buttons',
        direction="right", x=0.5, y=1.01, xanchor='center', yanchor='bottom',
    )]

まずはボタンから。各引数は以下。

  • active: グラフの初期表示プロットのインデックス(0は0番目のプロットを表示)
  • buttons: ボタン設定
  • type: buttonsでボタンを表示、dropdownでドロップダウン形式にできる
  • directon: ボタンを並べる方向
  • x, y: どの位置にボタンを並び始めるか
  • xanchor, yanchor: x, yの位置の基準

注意点はlistの中でdictを作成しないといけない点。listの中で作成するということは、裏を返せば複数ボタン作成可能ということ。

今回でいえばどのプロットを表示するかって話だったけど、別の位置に背景色を変更するとかのボタンも作成可能。

【plotly&ボタン】グラフに複数種のボタンを追加

続きを見る

スライダーの設定

sliders = [
    dict(
        active=0,
        currentvalue=dict(prefix='now: '),
        steps=set_menus()
    )
]

スライダーも同じように設定する。ボタンの時と異なる引数は以下。

  • currentvalue: スライダーの現在の値に関する設定
  • prefix: 現在の値に接頭辞をつける
  • steps: スライダー設定

こちらも同じようにlistの中にdictを入れないといけない。

goでボタンとスライダーを作成

# 各プロットの作成
plot = []
for order, y in data.items():
    d = go.Scatter(x=x, y=y, name=f"go-{order}", showlegend=True)
    plot.append(d)

ということで準備が終わったのでgoでのボタンとスライダーのグラフを作成。の前にプロットデータを作成、レイアウトの関数を定義しておく。

プロットデータとレイアウトの関数はgoでしか使用しないのでここで定義しておく。プロットデータのshowlegendTrueとしておくとプロットが1つでも凡例が出るようになる。

レイアウトに関しては初期グラフタイトルと横・縦軸の表示範囲、そしてボタンとスライダーの設定ができるように追加設定用のkwargsを入れた。

# レイアウトの作成
def set_layout(**kwargs):
    layout = go.Layout(
        title=dict(text='ALL',),  # 初期グラフタイトル
        xaxis_range=(-2.1, 2.1), yaxis_range=(-35, 35),
        **kwargs,  # 追加設定
    )
    return layout

軸の表示範囲を固定しておかないと各プロットごとに自動で範囲が調節されたり、プロットがはみ出たりしてキレイではない。

go x ボタン


まずはgoとボタンの組み合わせ。figdataにプロットデータのplotを、レイアウト部分にボタン情報を含んだset_layout関数を入れたらいい。

ボタンを押すことでプロットが変わることがわかるだろう。

# goでボタン
fig = go.Figure(data=plot, layout=set_layout(updatemenus=updatemenus))
fig.show()
save(fig=fig, config=None, save_name='go_buttons')

go x スライダー


スライダーも同じようにレイアウトにスライダーを入れたら完成。

# goでスライダー
fig = go.Figure(data=plot, layout=set_layout(sliders=sliders))
fig.show()
save(fig=fig, config=None, save_name='go_sliders')

go x ボタン&スライダー


やる意味はないけど、ボタンとスライダーを同時に設定することも可能。しかし、ボタンとスライダーは同期されておらず、片方を動かしてももう片方は止まったまま。

なので、同期するように設定しないと誤解を生みそうだ。というより、そもそもこのグラフでは両方はいらない。

# ボタンとスライダーを両方
layout = set_layout(updatemenus=updatemenus, sliders=sliders)
fig = go.Figure(data=plot, layout=layout)
fig.show()
save(fig=fig, config=None, save_name='go_buttons_sliders')

pxでボタンとスライダーを作成

最後にpxでも同じようにボタンとスライダーを作成する。ボタンについてはgoと似ているけど、スライダーに関してはちょっとトリッキーな方法で作成。

px x ボタン


pxのボタンの場合はすぐにできるというわけではなく、figを作成した後にupdatemenusを設定する。要するに後付け。

px.scatterの引数でボタン関連がないから仕方なくこのようにするしかない。また、デフォルトでは点のプロットとなる。

# pxのボタンの場合はレイアウトに後付けしないといけない
fig = px.scatter(df, x='x', y='y', color='order')
fig.update_layout(updatemenus=updatemenus)
fig.show()
save(fig=fig, config=None, save_name='px_buttons')

px x スライダー


スライダーについては後付けではなく、後削りの戦法。これはかなりトリッキーだが賢いと感じた。

どういうことかというと、スライダーというのがアニメーションから再生ボタンを削除したものという考えから、アニメーションを作成後に再生ボタンを削除する。

例えば以下のようのアニメーションを作成したとする。

# pxのスライダーはアニメーションから再生ボタンを消す
fig = px.scatter(
    df, x='x', y='y', color='order',
    animation_frame="order",  # アニメーションはオーダーごと
    range_x=(-2.1, 2.1), range_y=(-35, 35),
)

この時のfigの中身は以下。

ここから再生ボタン部分を削除する。再生ボタンはupdatemenusでしか使用しないから、実質updatemunusを削除したのと同じ。

fig["layout"].pop("updatemenus")  # 再生ボタンを削除

あとはシンプルにfigを表示してグラフを保存すればいい。まとめると以下。

# pxのスライダーはアニメーションから再生ボタンを消す
fig = px.scatter(
    df, x='x', y='y', color='order',
    animation_frame="order",  # アニメーションはオーダーごと
    range_x=(-2.1, 2.1), range_y=(-35, 35),
)
fig["layout"].pop("updatemenus")  # 再生ボタンを削除

fig.show()
save(fig=fig, config=None, save_name='px_sliders')

px x ボタン&スライダー


最後にpxとボタンとスライダーのグラフを作成したが、スライダーでupdatemenusを消さなければいけないのでとりあえずアニメーションにボタンをつけた。

するとバグった。全プロット表示とorder1がそれぞれ再生ボタンと停止ボタンとなってしまい、使用できない。さらにボタンを押すとプロットが消える。

これだと実用性がないので、使用する際にはうまく両立できるように工夫しないといけない。

# pxでボタンとスライダーを同時するとバグる

fig = px.scatter(
    df, x='x', y='y', color='order',
    animation_frame="order",  # アニメーションはオーダーごと
    range_x=(-2.1, 2.1), range_y=(-35, 35),
)
fig.update_layout(updatemenus=updatemenus)
# fig["layout"].pop("updatemenus")  # 再生ボタンを削除

fig.show()
save(fig=fig, config=None, save_name='px_buttons_sliders')

なお、updatemenusを設定した後に削除すると、普通にスライダーとなる。そりゃそうだ。消したもん

ボタンは共通点多し、スライダーは結構異なる

今回はplotlygopxを使用してボタンを描く方法とスライダーを描く方法について解説した。

それぞれでグラフを描く方法は異なるけど、ボタンの指定方法は同じだったので、ボタンについては好みになりそう。

一方でスライダーに関しては大きく異なるのでスライダーはデータの作成方法や指定のしやすさで決めるのが良さそうだ。

関連記事

【px&animation】plotly.expressでアニメーションのグラフを作成

続きを見る

【Plotly&animation】Plotlyのgoでアニメーションを作成

続きを見る

【px&facet】plotly.expressでsubplotsを描く

続きを見る

【plotly&ボタン】plotlyのupdatemenusに2回押し対応のbuttonsを追加

続きを見る

ガジェット

2023/9/18

【デスクツアー2022下半期】モノは少なく、でも効率的に Desk Updating #0

今回はガジェットブロガーなのにデスク環境を構築していない執筆者の ...

ライフハック

2023/9/16

【Audible vs YouTube Premium】耳で聴く音声学習コンテンツを比較

ワイヤレスイヤホンが普及し耳で学習することへのハードルが格段に下 ...

完全ワイヤレスイヤホン(TWS)

2023/9/18

【SENNHEISER MOMENTUM True Wireless 3レビュー】全てが整ったイヤホン

今回は高音質・高機能なSENNHEISERのフラグシップ完全ワイヤレスイヤホン「SENNH ...

ライフハック

2023/3/11

【YouTube Premiumとは】メリットしかないから全員入れ

今回はYouTube Premiumを実際に使ってみてどうなのか、どんなメリット/デメリット ...

マウス

2023/8/17

【Logicool MX ERGOレビュー】疲れない作業効率重視トラックボールマウス

こんな人におすすめ トラックボールマウスの王道Logicool MX ERGOが気になるけどऩ ...

ベストバイ

2023/9/18

【ベストバイ2022】今年買って良かったモノのトップ10

2022年ベストバイ この1年を振り返って執筆者は何を買ったのか。ガジェッ& ...

スマホ

2023/1/15

【楽天モバイル×povo2.0の併用】月1,000円の保険付きデュアルSIM運用

こんな人におすすめ 楽天モバイルとpovo2.0のデュアルSIM運用って実際のとこ ...

マウス

2023/9/16

【Logicool MX ERGO vs MX Master 3】ERGOをメインにした決定的な理由

こんな疑問・お悩みを持っている人におすすめ 執筆者はLogicoolのハイエンӠ ...

macOSアプリケーション

2022/9/30

【Chrome拡張機能】便利で効率的に作業できるおすすめの拡張機能を18個紹介する

こんな人におすすめ Chromeの拡張機能を入れたいけど、調べても同じような ...

macOSアプリケーション

2023/5/3

【Automator活用術】Macで生産性を上げる作業の自動化術

今回はMacに標準でインストールされているアプリ「Automator」を使ってできる ...

Pythonを学びたいけど独学できる時間なんてない人へのすゝめ

執筆者は大学の研究室・大学院にて独学でPythonを習得した。

でも社会人になったら独学で行うには時間も体力もなくて大変だ。

時間がない社会人だからこそプロの教えを乞うのが効率的。

ここでは色んなタイプに合ったプログラミングスクールの紹介をする。

  • この記事を書いた人

メガネ

Webエンジニア駆け出し。独学のPythonで天文学系の大学院を修了。常時金欠のガジェット好きでM2 Pro MacBook Pro(30万円) x Galaxy S22 Ultra(17万円)使いの狂人。自己紹介と半生→変わって楽しいの繰り返しレビュー依頼など→お問い合わせ運営者情報、TwitterX@m_ten_pa、 YouTube@megatenpa、 Threads@megatenpa

-Pythonでの比較
-, , , ,