2025-09-16

Ta-Lib を Python で利用する

TA-Lib, Technical Analysis Library は 2001 年にリリースされ、20 年以上経った今でも広く利用されている著名なアルゴリズムを提供しています。コードは安定しており、長年にわたる検証を経ています。200 以上のテクニカル指標をサポートしており、API は C/C++ で記述されており Python ラッパー (wrapper) も提供されています。TA-Lib は BSD License (BSD-2-Clause license) の元で配布されているオープンソースのライブラリです。

以前は Linux 上で TA-Lib の Python 用パッケージを pip でインストールしてもビルドが必要で、しかもエラーでビルドできませんでした。自力でエラーを解決できなかったので TA-Lib の利用を避けていました。しかし最近の TA-Lib のバージョンの Python 用パッケージでは難なくインストールできることが判りました。

そこで今更ですが TA-Lib の使い方をおぼえようと、Jupyter Lab 上でテクニカル指標のいくつかをプロットしてみたので、備忘録的に内容をまとめました。

下記の OS 環境で動作確認をしています。

Fedora Linux Workstation 42 x86_64
Python 3.13.7
JupyterLab 4.4.7
matplotlib 3.10.6
mplfinance 0.12.10b0
numpy 2.3.3
pandas 2.3.2
ta-lib 0.6.7
yfinance 0.2.65

サンプル

ライブラリをインポート

最初に利用するライブラリをまとめてインポートします。

import matplotlib.font_manager as fm
import matplotlib.pyplot as plt
import mplfinance as mpf
import numpy as np
import pandas as pd
import yfinance as yf
from talib import BBANDS, MACD, MFI, MOM, OBV, RSI, SAR, STOCH

yfinance で日経平均株価指数の過去データを取得

サンプルとして、今年の 1 月から半年間の日足データを取得します。

symbol = "^N225"
ticker = yf.Ticker(symbol)
df = ticker.history(start="2025-01-01", end="2025-07-01", interval="1d")

サンプル期間より少し古いデータからも取得しておきます。これでテクニカル指標を算出して、サンプルの期間の最初から指標がプロットされるようにします。

df2 = ticker.history(start="2024-10-01", end="2025-07-01", interval="1d")

mplfinance でチャートを作成

サンプル期間の日足データをローソク足チャートと出来高の棒グラフを並べてプロットしました。

fig = plt.figure(figsize=(8, 4))
ax = dict()
n = 2
gs = fig.add_gridspec(
    n, 1, wspace=0.0, hspace=0.0, height_ratios=[3 if i == 0 else 1 for i in range(n)]
)
for i, axis in enumerate(gs.subplots(sharex="col")):
    ax[i] = axis
    ax[i].grid()

mpf.plot(
    df,
    type="candle",
    style="default",
    datetime_format="%m/%d",
    xrotation=0,
    ax=ax[0],
    volume=ax[1],
)
ax[0].set_title(f"{ticker.info['longName']} ({symbol})")

plt.tight_layout()
# plt.savefig("screenshots/n225_default.png")
plt.show()

Bollinger bands

過去 20 日間の移動平均、移動標準偏差 +3σ, +2σ, +1σ, mean, -1σ, -2σ, -3σ でボリンジャーバンドを作成しました。

fig, ax = plt.subplots(figsize=(8, 3))

# BBANDS - Bollinger Bands
# upperband, middleband, lowerband = BBANDS(real, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0)
period = 20
mv_upper_1, mv_mean, mv_lower_1 = BBANDS(df2["Close"], period, 1, 1)
mv_upper_2, _, mv_lower_2 = BBANDS(df2["Close"], period, 2, 2)
mv_upper_3, _, mv_lower_3 = BBANDS(df2["Close"], period, 3, 3)

apds = [
    mpf.make_addplot(
        mv_upper_3[df.index],
        width=1,
        color="C0",
        linestyle="dotted",
        label="+3σ",
        ax=ax,
    ),
    mpf.make_addplot(
        mv_upper_2[df.index],
        width=0.9,
        color="C1",
        linestyle="dashdot",
        label="+2σ",
        ax=ax,
    ),
    mpf.make_addplot(
        mv_upper_1[df.index],
        width=0.75,
        color="C2",
        linestyle="dashed",
        label="+1σ",
        ax=ax,
    ),
    mpf.make_addplot(
        mv_mean[df.index],
        width=1,
        color="C3",
        linestyle="solid",
        label="Mean",
        ax=ax,
    ),
    mpf.make_addplot(
        mv_lower_1[df.index],
        width=0.75,
        color="C4",
        linestyle="dashed",
        label="-1σ",
        ax=ax,
    ),
    mpf.make_addplot(
        mv_lower_2[df.index],
        width=0.9,
        color="C5",
        linestyle="dashdot",
        label="-2σ",
        ax=ax,
    ),
    mpf.make_addplot(
        mv_lower_3[df.index],
        width=1,
        color="C6",
        linestyle="dotted",
        label="-3σ",
        ax=ax,
    ),
]
mpf.plot(
    df,
    type="candle",
    style="default",
    addplot=apds,
    datetime_format="%m/%d",
    xrotation=0,
    update_width_config=dict(candle_linewidth=0.75),
    ax=ax,
)
ax.grid()
ax.legend(fontsize=7)
ax.set_title(
    f"{ticker.info['longName']} ({symbol})\nwith Bollinger Bands (period={period}days)"
)

plt.tight_layout()
# plt.savefig("screenshots/n225_talib_bbands.png")
plt.show()

Parabolic SAR

AF step=0.02, max=0.2 で Parabolic SAR をプロットしました。上昇下降トレンドの情報が無いので、灰色の丸点でプロットしました。

fig, ax = plt.subplots(figsize=(8, 3))

# SAR - Parabolic SAR
# real = SAR(high, low, acceleration=0, maximum=0)
af_step = 0.02
af_max = 0.2
sar = SAR(df2["High"], df2["Low"], af_step, af_max)

apds = [
    mpf.make_addplot(
        sar[df.index],
        type="scatter",
        marker='o',
        markersize=3,
        color="darkgray",
        ax=ax,
    ),
]
mpf.plot(
    df,
    type="candle",
    style="default",
    addplot=apds,
    datetime_format="%m/%d",
    xrotation=0,
    update_width_config=dict(candle_linewidth=0.75),
    ax=ax,
)
ax.grid()
ax.set_title(
    f"{ticker.info['longName']} ({symbol})\nwith Parabolic SAR (AF step={af_step}, max={af_max})"
)

plt.tight_layout()
# plt.savefig("screenshots/n225_talib_sar.png")
plt.show()

Momentum

過去 10 日間のデータでモメンタムを算出しました。

fig = plt.figure(figsize=(8, 4))
ax = dict()
n = 2
gs = fig.add_gridspec(
    n, 1, wspace=0.0, hspace=0.0, height_ratios=[2 if i == 0 else 1 for i in range(n)]
)
for i, axis in enumerate(gs.subplots(sharex="col")):
    ax[i] = axis
    ax[i].grid()

# MOM - Momentum
# real = MOM(real, timeperiod=10)
period = 10
mom = MOM(df2["Close"], period)
apds = [
    mpf.make_addplot(
        mom[df.index],
        width=1,
        color="C0",
        linestyle="solid",
        ax=ax[1],
    ),
]
mpf.plot(
    df,
    type="candle",
    style="default",
    addplot=apds,
    datetime_format="%m/%d",
    xrotation=0,
    ax=ax[0],
)
ax[1].set_ylabel("Momentum")
ax[0].set_title(
    f"{ticker.info['longName']} ({symbol})\nwith Momentum (period={period}days)"
)

plt.tight_layout()
# plt.savefig("screenshots/n225_talib_mom.png")
plt.show()

RSI, Relative Strength Index

過去 14 日間のデータで RSI を算出しました。

fig = plt.figure(figsize=(8, 4))
ax = dict()
n = 2
gs = fig.add_gridspec(
    n, 1, wspace=0.0, hspace=0.0, height_ratios=[2 if i == 0 else 1 for i in range(n)]
)
for i, axis in enumerate(gs.subplots(sharex="col")):
    ax[i] = axis
    ax[i].grid()

# RSI - Relative Strength Index
# real = RSI(real, timeperiod=14)
period = 14
rsi = RSI(df2["Close"], period)
apds = [
    mpf.make_addplot(
        rsi[df.index],
        width=1,
        color="C0",
        linestyle="solid",
        ax=ax[1],
    ),
]
mpf.plot(
    df,
    type="candle",
    style="default",
    addplot=apds,
    datetime_format="%m/%d",
    xrotation=0,
    ax=ax[0],
)
ax[0].set_title(f"{ticker.info['longName']} ({symbol})\nwith RSI (period={period}days)")
ax[1].set_ylabel("RSI")
ax[1].set_ylim(0, 100)
ax[1].axhline(30, color="black", linewidth=0.5)
ax[1].axhline(70, color="black", linewidth=0.5)

plt.tight_layout()
# plt.savefig("screenshots/n225_talib_rsi.png")
plt.show()

Stochastic oscillator

スローストキャスティクスをデフォルトのパラメータのままでプロットしています。

fig = plt.figure(figsize=(8, 4))
ax = dict()
n = 2
gs = fig.add_gridspec(
    n, 1, wspace=0.0, hspace=0.0, height_ratios=[2 if i == 0 else 1 for i in range(n)]
)
for i, axis in enumerate(gs.subplots(sharex="col")):
    ax[i] = axis
    ax[i].grid()

# STOCH - Stochastic
# slowk, slowd = STOCH(high, low, close, fastk_period=5, slowk_period=3, slowk_matype=0, slowd_period=3, slowd_matype=0)
slowk, slowd = STOCH(df2["High"], df2["Low"], df2["Close"])

apds = [
    mpf.make_addplot(
        slowk[df.index],
        width=1,
        color="C0",
        linestyle="solid",
        label="Slow%K",
        ax=ax[1],
    ),
    mpf.make_addplot(
        slowd[df.index],
        width=1,
        color="C1",
        linestyle="solid",
        label="Slow%D",
        ax=ax[1],
    ),
]
mpf.plot(
    df,
    type="candle",
    style="default",
    addplot=apds,
    datetime_format="%m/%d",
    xrotation=0,
    ax=ax[0],
)
ax[0].set_title(f"{ticker.info['longName']} ({symbol})\nwith Stochastic oscillator")
ax[1].set_ylabel("Stochastic")
ax[1].set_ylim(0, 100)
ax[1].axhline(20, color="black", linewidth=0.5)
ax[1].axhline(80, color="black", linewidth=0.5)
ax[1].legend(fontsize=7)

plt.tight_layout()
# plt.savefig("screenshots/n225_talib_stoch.png")
plt.show()

MACD, Moving Average Convergence Divergence

MACD もデフォルトのパラメータでプロットしています。MACD のヒストグラムは正負で色を変えたかったのですが、すぐに出来なかったので単色にしてしまいました。

fig = plt.figure(figsize=(8, 4))
ax = dict()
n = 2
gs = fig.add_gridspec(
    n, 1, wspace=0.0, hspace=0.0, height_ratios=[2 if i == 0 else 1 for i in range(n)]
)
for i, axis in enumerate(gs.subplots(sharex="col")):
    ax[i] = axis
    ax[i].grid()

# MACD - Moving Average Convergence/Divergence
# macd, macdsignal, macdhist = MACD(real, fastperiod=12, slowperiod=26, signalperiod=9)
period_fast = 12
period_slow = 26
period_signal = 9
macd, signal, macdhist = MACD(df2["Close"], period_fast, period_slow, period_signal)

apds = [
    mpf.make_addplot(
        macd[df.index],
        width=1,
        color="C0",
        linestyle="solid",
        label="MACD",
        ax=ax[1],
    ),
    mpf.make_addplot(
        signal[df.index],
        width=1,
        color="C1",
        linestyle="solid",
        label="Signal",
        ax=ax[1],
    ),
    mpf.make_addplot(
        macdhist[df.index],
        type="bar",
        color="C2",
        ax=ax[1],
    ),
]
mpf.plot(
    df,
    type="candle",
    style="default",
    addplot=apds,
    datetime_format="%m/%d",
    xrotation=0,
    ax=ax[0],
)
ax[0].set_title(
    f"{ticker.info['longName']} ({symbol})\nwith MACD [{period_fast}, {period_slow}, {period_signal}]"
)
ax[1].set_ylabel("MACD")
ax[1].legend(fontsize=7)

plt.tight_layout()
# plt.savefig("screenshots/n225_talib_macd.png")
plt.show()

OBV, On Balance Volume

OBV は終値と出来高から算出する指標です。

fig = plt.figure(figsize=(8, 5))
ax = dict()
n = 3
gs = fig.add_gridspec(
    n, 1, wspace=0.0, hspace=0.0, height_ratios=[2 if i == 0 else 1 for i in range(n)]
)
for i, axis in enumerate(gs.subplots(sharex="col")):
    ax[i] = axis
    ax[i].grid()

# OBV - On Balance Volume
# real = OBV(close, volume)
obv = OBV(df2["Close"], df2["Volume"])

apds = [
    mpf.make_addplot(
        obv[df.index],
        width=1,
        color="C0",
        linestyle="solid",
        ax=ax[2],
    ),
]
mpf.plot(
    df,
    type="candle",
    style="default",
    addplot=apds,
    datetime_format="%m/%d",
    xrotation=0,
    ax=ax[0],
    volume=ax[1],
)
ax[0].set_title(f"{ticker.info['longName']} ({symbol})\nwith OBV")
ax[2].set_ylabel("OBV")

plt.tight_layout()
# plt.savefig("screenshots/n225_talib_obv.png")
plt.show()

MFI, Money Flow Index

MFI も、株価と出来高から算出する指標です。

fig = plt.figure(figsize=(8, 5))
ax = dict()
n = 3
gs = fig.add_gridspec(
    n, 1, wspace=0.0, hspace=0.0, height_ratios=[2 if i == 0 else 1 for i in range(n)]
)
for i, axis in enumerate(gs.subplots(sharex="col")):
    ax[i] = axis
    ax[i].grid()

# MFI - Money Flow Index
# NOTE: The MFI function has an unstable period.
# real = MFI(high, low, close, volume, timeperiod=14)
period = 14
mfi = MFI(df2["High"], df2["Low"], df2["Close"], df2["Volume"], period)

apds = [
    mpf.make_addplot(
        mfi[df.index],
        width=1,
        color="C0",
        linestyle="solid",
        ax=ax[2],
    ),
]
mpf.plot(
    df,
    type="candle",
    style="default",
    addplot=apds,
    datetime_format="%m/%d",
    xrotation=0,
    ax=ax[0],
    volume=ax[1],
)
ax[0].set_title(f"{ticker.info['longName']} ({symbol})\nwith MFI (period={period}days)")
ax[2].axhline(20, color="black", linewidth=0.5)
ax[2].axhline(80, color="black", linewidth=0.5)
ax[2].set_ylabel("MFI")
ax[2].set_ylim(0, 100)

plt.tight_layout()
# plt.savefig("screenshots/n225_talib_mfi.png")
plt.show()

参考サイト

  1. TA-Lib - Technical Analysis Library
  2. TA-Lib/ta-lib: TA-Lib (Core C Library)
  3. TA-Lib/ta-lib-python: Python wrapper for TA-Lib
  4. TA-Lib · PyPI

 

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ オープンソースへ
にほんブログ村

オープンソース - ブログ村ハッシュタグ
#オープンソース



このエントリーをはてなブックマークに追加

2025-07-27

deepin 25 をインストール

deepin(深度操作系统)は、中国に拠点をおく UnionTech(统信软件)の子会社である Wuhan Deepin Technology Co., Ltd.(武汉深之度科技有限公司)が開発している Linux ディストロです。デスクトップ環境に Qt を利用した独自の DDE (Deepin Desktop Environment) を採用しています。

deepin は DDE をデスクトップ環境にした Debian ベースのディストロだと単純に思っていましたが、そんな単純なプロジェクトではないようです。Deepin_Profile | DeepinWiki によると、2022 年以降の開発計画では、Linux カーネルをベースに独自のディストロへの展開を目指しているように見えます。一部を抜粋しました。

Plan of Deepin after 2022 year

  • based on kernel
graph LR 1(Linux Kernel)---2(Deepin) 2(Deepin)---3(UniontechOS) 2(Deepin)---4(Other OS)

deepin 25

2025-06-21 に deepin 25 がリリースされたので、遅ればせながら評価用の PC にインストールしてみました。インストール用の ISO イメージは下記からダウンロードできます。

リリースノートによると、このリリースの新機能は以下の 5 点になっています。

  1. DDE 7.0
    • DDE は Qt で記述された deepin 独自のデスクトップ環境です。
    • QMLを使用して数多くのデスクトップコンポーネントを再構築しました。
  2. UOS AI
    • UOS AI という音声 AI アシスタントが利用可能になりました。
    • 話すだけで操作
      • システムが聴き取ります。画面の明るさを調整したり、迅速に会議を作成したい場合、自然言語でシステムにコマンドを発行してみてください!
      • 音声でもテキストでもシステムは理解し、面倒なメニュークリックから解放されます。
    • デュアルモードエンジン
      • DeepSeek、Baidu Qianfan、iFlytek Sparkなどの主要なオンライン大規模モデルに接続し、クラウドコンピューティングのパワーを活用できます。
    • エージェントストア
      • AIアシスタントの新しい「エージェントストア」から、さまざまな分野のエージェントをダウンロードし、AIの応用シーンを拡大し、よりパーソナライズされたAIを実現できます。
  3. Solid (deepin Immutable System)
    • Solid というイミュータブル(読み取り専用)のシステムが導入されました。
    • 読み取り専用保護
      • /usr/bin などのシステムコアディレクトリを読み取り専用として強制マウントすることで、システムはユーザーによる誤操作やマルウェアによるシステムコアの改変を根本的に阻止し長期的に安定した動作を保証します。
    • セカンドレベルのスナップショット
      • システム更新のたびに、システムは自動的にバックアップスナップショットを作成します。更新中に予期せぬ問題が発生した場合でも、再起動時に最後の正常な状態に自動的にロールバックするため、「更新によるシステム破損」の不安を解消します。
    • 安心復元
      • 公共のコンピュータや展示用デバイスなどのシナリオ向けに設計された「安心復元」機能は、再起動時に使用履歴を自動的に削除するほか、セキュリティと効率のバランスを調整するためのホワイトリスト設定もサポートしています。
  4. Linyaps: Universal Adaptability,Deep Ecosystem Roots
    • Linyaps はコンテナ化されたサンドボックス技術を採用し、アプリケーションとその依存関係ライブラリを完全に隔離します。
      • 単一のLinyapパッケージは Debian、Ubuntu、Arch、Fedora、openEuler を含む7つの主要なディストリビューション上で直接実行可能です。
      • マルチアーキテクチャ対応
        • AMD64、ARM64、LoongArch64など、主要な CPU アーキテクチャに対する包括的なサポートを提供しています。
        • Linyaps のエコシステムには、オフィス、開発、エンターテインメントなど多様なニーズに対応する 5000 を超えるソフトウェアパッケージがホストされています。
  5. Community Power Tools
    • Distrobox サブシステム
      • Debian 12、Ubuntu (20.04/24.04)、Arch、Fedora (41/42) などの主要なディストリビューションのサブシステムイメージを App Store から直接インストールでき、慣れた開発やテスト環境を自由に構築できます。
    • Treeland ウィンドウコンポジター (プレビュー / 探索)
      • 独自開発したコンポジターは、アニメーションの滑らかさを 40% 向上させ、マルチフィンガータッチパッドジェスチャー追跡をサポートし、シルクのような滑らかな操作を実現します。
    • クロスデバイスコラボレーション
      • PC 間のキーボード/マウスとクリップボード共有をだけでなく、スマートフォンと PC 間の双方向制御を実現。
      • スマートフォンのメッセージに返信したり、スマートフォンのアプリをパソコンの大画面で操作したりすることで、シームレスで統合されたワークフローを構築可能。
    • 主要アーキテクチャ対応
      • AMD64 / ARM64 / LoongArch64 / RISC-V アーキテクチャに対応。
      • 対応デバイスには Raspberry Pi 4B+、Radxa Rock5B/5B+、ROCK 5 ITX マザーボードなどが含まれます。
    • グローバル対応
      • インストーラーに17言語を追加。
      • システムレベルの翻訳は51言語に対応。
      • App Store は地域別のコンテンツ配信をサポートし、グローバルユーザーに一貫したローカライズされた体験を提供。

deepin 25 の使用感や詳細な特徴などについては、少し調査する時間が必要です。今回は日本語用入力メソッドの設定方法を紹介するだけにとどめます。

日本語用入力メソッドの設定

日本語用入力メソッドを利用するにはパッケージのインストールと設定が必要になります。

パッケージのインストールには Debian と同じように apt コマンドを利用できます。ここでは、fcitx5-mozc をインストールして日本語用入力メソッドを利用できるようにする方法を紹介します。

bitwalk@deepin-PC:~$ sudo apt install fcitx5-mozc
[sudo] bitwalk のパスワード:
Verification successful
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています... 完了        
状態情報を読み取っています... 完了        
以下の追加パッケージがインストールされます:
  fcitx-mozc-data libprotobuf32 mozc-data mozc-server mozc-utils-gui
提案パッケージ:
  ibus-qt5
以下のパッケージが新たにインストールされます:
  fcitx-mozc-data fcitx5-mozc libprotobuf32 mozc-data mozc-server mozc-utils-gui
アップグレード: 0 個、新規インストール: 6 個、削除: 0 個、保留: 7 個。
13.8 MB のアーカイブを取得する必要があります。
この操作後に追加で 27.4 MB のディスク容量が消費されます。
続行しますか? [Y/n] y
取得:1 https://community-packages.deepin.com/beige crimson/main amd64 mozc-data all 2.28.4715.102+dfsg-2.3deepin1 [16.8 kB]
取得:2 https://community-packages.deepin.com/beige crimson/main amd64 fcitx-mozc-data all 2.28.4715.102+dfsg-2.3deepin1 [8,408 B]
取得:3 https://community-packages.deepin.com/beige crimson/main amd64 libprotobuf32 amd64 3.21.12-8deepin2 [941 kB]
取得:4 https://community-packages.deepin.com/beige crimson/main amd64 mozc-server amd64 2.28.4715.102+dfsg-2.3deepin1 [11.7 MB]
取得:5 https://community-packages.deepin.com/beige crimson/main amd64 fcitx5-mozc amd64 2.28.4715.102+dfsg-2.3deepin1 [276 kB]
取得:6 https://community-packages.deepin.com/beige crimson/main amd64 mozc-utils-gui amd64 2.28.4715.102+dfsg-2.3deepin1 [856 kB]
13.8 MB を 37秒 で取得しました (376 kB/s)                                                                    
以前に未選択のパッケージ mozc-data を選択しています。
...
(途中省略)
...
libprotobuf32:amd64 (3.21.12-8deepin2) を設定しています ...
mozc-data (2.28.4715.102+dfsg-2.3deepin1) を設定しています ...
fcitx-mozc-data (2.28.4715.102+dfsg-2.3deepin1) を設定しています ...
mozc-server (2.28.4715.102+dfsg-2.3deepin1) を設定しています ...
mozc-utils-gui (2.28.4715.102+dfsg-2.3deepin1) を設定しています ...
fcitx5-mozc:amd64 (2.28.4715.102+dfsg-2.3deepin1) を設定しています ...
desktop-file-utils (0.28-1) のトリガを処理しています ...
hicolor-icon-theme (0.17-2) のトリガを処理しています ...
libc-bin (2.38-6deepin13+rb1) のトリガを処理しています ...
bamfdaemon (0.5.6+repack-1) のトリガを処理しています ...
Rebuilding /usr/share/applications/bamf-2.index...
bitwalk@deepin-PC:~$ im-config -n fcitx5
bitwalk@deepin-PC:~$

コントロールセンターを起動して、左側の「デバイス」タブをクリック、右側画面の「キーボード」をクリックして表示される画面下側の「入力メソッド」をクリックした画面で、以下のように入力メソッドの追加をクリックして入力メソッドを追加します。

なお、システムを再起動した後に、入力メソッドの追加の一覧に Mozc が表示されました。

また、「キーボード - 英語(US)」は、日本語キーボードのレイアウトの場合は不要です。この例では、インストールした廉価な中華PCのキーボードが英語レイアウトだったので、英語のレイアウトも残しています。

日本語用入力メソッドを有効にするには Ctrl + スペース を押下します。

米国依存を減らしたい中国

華為 (Huawei) がスマートフォン向けに HarmonyOS を開発しているように、deepin は Windows に替わる OS を目指しているのでしょうか。

Wikipedia の Unity Operating System(UOS, 统一操作系统)の説明によると、一般ユーザー向けが deepin だとあります。UOS は明確に Windows 代替になることを目指しているプロジェクトです。

deepin の Community Edition は多言語に対応していますが、UOS のダウンロードサイトは英語の画面が提供されておらず解読が難しいです。しかし URL は英語表記 (www.chinauos.com/resource/download-professional) なので、こちらが Professional 版(商用版?)のダウンロードサイトであると推測できます。

例えば「统信UOS桌面专业版」は、UnionTech UOS Desktop Professional Edition です。

ちなみに statcounter で中国で使用されている OS のマーケットシェアを確認すると、依然 Windows のシェアが高いように見えます。それでも UOS が中国国内の Loongson などの CPU への対応を進めていることから、徐々にシェアは変化いくのかもしれません。

Source: StatCounter Global Stats - OS Market Share

参考サイト

  1. Deepin - Deepin Linux Distribution Wiki | DeepinWiki

 

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ オープンソースへ
にほんブログ村

オープンソース - ブログ村ハッシュタグ
#オープンソース



このエントリーをはてなブックマークに追加

2025-07-11

PySide6 でソケット通信

PySide (Qt for Python) は、Qt(キュート)の Python バインディングで、GUI などを構築するためのクロスプラットフォームなライブラリです。Linux, macOS および Microsoft Windows をサポートしています。配布ライセンスは LGPL で公開されています。

Qt Network を利用して GUI アプリの間でソケット通信をしてみたくて簡単なサンプルがないか探したところ、下記に PySide6 のサンプルがありました。

同一の PC 上 (127.0.0.0) で動作するように作られたサーバーとクライアントの簡単なサンプルです。まさにこんなサンプルが欲しかったのですが、使いやすいように少々手を加えました。

下記の OS 環境で動作確認をしています。

Fedora Linux Workstation 42 x86_64
Python 3.13.5
PySide6 6.9.1

サーバー (qt_tcpsocket_server.py) とクライアント (qt_tcpsocket_client.py) のサンプルを起動し、クライアント側の Connect ボタンをクリックすると、サーバー側のウィンドウに Connected from ... のメッセージ、クライアント側のウィンドウに Connected to server. のメッセージが表示されます。

クライアント側の Message: のエントリに文字列を入力して Enter キーを押すと、サーバー側へ入力した文字列が送信され、クライアント側でもサーバーが受信した文字列が表示されます。

クライアント側の IP アドレスと Port 番号の入力欄は将来の拡張用で、現在のところデフォルトの設定を変更しても動作しません。

以下に 2 つのサンプルのコードを示しました(不具合が見つかり次第、更新しています)。

qt_tcpsocket_server.py
qt_tcpsocket_client.py

参考サイト

  1. PySide6.QtNetwork.QTcpSocket - Qt for Python
  2. PySide6.QtNetwork.QTcpServer - Qt for Python
  3. PySide6.QtNetwork.QAbstractSocket - Qt for Python

 

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ オープンソースへ
にほんブログ村

オープンソース - ブログ村ハッシュタグ
#オープンソース



このエントリーをはてなブックマークに追加

2025-06-25

AlmaLinux 10 と RDP

AlmaLinux OS はオープンソースでコミュニティ主導のエンタープライズ Linux ディストロであり、RHEL とバイナリ互換性があります。AlmaLinux OS Foundation は、AlmaLinux OS コミュニティの利益のために設立された 501 (c) (6) の非営利団体です。

先月 Red Hat Enterprise Linux 10(以降 RHEL10)がリリースされて、早速 RHEL10 をリリースしようと思ったのですが、RHEL10 がサポートする AMD および Intel 64 ビットアーキテクチャーは x86-64-v3 である必要があります [1]。RHEL9 をインストールして稼働させていたファイルサーバーの安物のミニ PC は、あいにく RHEL10 へのアップグレードができません。

サーバーを新調したかったのですが、ファイルサーバや cron で集計作業をさせる程度の用途ではまだまだ使えるのでちょっと勿体ない。そこで新しい OS を試したい欲求を満たすため、x86-64-v2 対応のイメージも公開している AlmaLinux 10 へ乗り換えることにしました [2]

xrdp パッケージが見つからない!

AlmaLinxu 10 (v2) のインストールが終わり、今までのように xrdp をインストールして、メイン PC の Fedora Linux から Remmina で RDP 接続して Windows と同様に AlmaLinux 10 (v2) もリモートデスクトップとして利用しようとしたのですが、xrdp パッケージが見つかりません。

さて、どうしたものかと代替案を探していたところ、RHEL10 のドキュメントに答えがありました。

あとでじっくり読み直したら、「1.2. GNOME リモートログインの設定」だけで今までのリモートデスクトップ用途を実現できたように思いましたが、最初は 1.1, 1.2 を設定して 1.3 を試しました。なお、gnome-remote-desktop パッケージは既にインストールされておりました。

設定は上記のドキュメントの通り GNOME の設定をしてファイヤウォールルールの設定をすれば使えるようになるはずですが、なぜかうまくいきませんでした。Cockpit にログインして SELinux access control errors を確認すると以下のメッセージが出ていました。

  • SELinux により、/usr/libexec/gnome-remote-desktop-daemon による read アクセスが、ディレクトリー /var/lib/sss/pubconf/krb5.include.d で拒否されました。

下記のコマンドを実行したところ、RDP による接続ができるようになりました。

sudo ausearch -c 'gnome-remote-de' --raw | audit2allow -M my-gnomeremotede
sudo semodule -i my-gnomeremotede.pp

GNOME の Connections(Fedora Linux 42 の gnome-connections) から RDP 接続できることを確認しましたが、使い慣れている Remmina を使って接続しています。

接続後のログイン画面

xrdp サーバを使っていた時には Remmina 側でユーザー名とパスワードを設定しておけばダイレクトにデスクトップ画面が表示されましたが、GNOME のリモートデスクトップ接続では、ユーザー名とパスワードを Remmina に設定しても必ずログイン画面が表示されるようです。

ログイン後のデスクトップ画面

参考サイト

  1. RHEL 10 の導入における検討事項 | Red Hat Enterprise Linux(第2章 アーキテクチャー)
  2. AlmaLinux OS - Forever-Free Enterprise-Grade Operating System [2025-05-27]

 

ずっと xrdp をインストールして RDP サーバとして利用していたので GNOME のリモート接続の機能を利用したことがありませんでした。

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ オープンソースへ
にほんブログ村

オープンソース - ブログ村ハッシュタグ
#オープンソース



このエントリーをはてなブックマークに追加

2025-05-28

【備忘録】Matplotlib で保存するプロットのデフォルト名

Matplotlib は、Python と NumPy のためのプロットライブラリです。Tkinter、wxPython、Qt、GTK のような汎用 GUI ツールキットを使ったアプリケーションにプロットを埋め込むためのオブジェクト指向 API を提供しています。

Wikipedia より引用、翻訳

JupyterLab 上では、Matplotlib でプロットしたチャートを保存するには、plt.savefig(filename) を使うのですが、そうでないときは、以下のようにチャート (figure) の下にナビゲータバーが表示されているので、右端のフロッピーディスクを模した保存用ボタンをクリックして画像として保存します。

保存用のダイアログに表示されたデフォルトのファイル名は Figure_1 になっています。

このデフォルトのファイル名を変更したい

些細なことのようですが、このデフォルトのファイル名 Figure_1 を変えられないかどうか調べたところ、Stack Overflow [1] に該当するやりとりを見つけました。保存するファイルのデフォルトのファイル名を変更するサンプルを紹介します。

下記の OS 環境で動作確認をしています。

Fedora Linux 42 Workstation x86_64
Python 3.13.3
matplotlib 3.10.3
numpy 2.2.6

サンプル・コードを以下の通りです。

sample_mpl_save.py
# This is based on the following sample:
# https://matplotlib.org/stable/users/getting_started/
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 2 * np.pi, 200)
y = np.sin(x)

fig, ax = plt.subplots()
ax.plot(x, y)

# デフォルトのファイル名を Untitled に設定
c = fig.canvas
ext = c.get_default_filetype()
c.get_default_filename = lambda: f"Untitled.{ext}"

plt.show()

一手間加えるだけで、デフォルトのファイル名を Figure_1 から Untitled へ変更できました。

ちなみに、PySide6 に Matplotlib のチャートを埋め込んで Matplotlib のナビゲーションツールバー (NavigationToolbar2QT) を利用してチャートを画像形式で保存する時には、デフォルトのファイル名が image.png になります。さすがに GUI アプリではデフォルトの保存ファイル名を自由に設定したいので、同じような考え方でファイル名を変更しています。

参考サイト

  1. python - How to change default filename from Matplotlib NavigationToolbar in a PyQt5 application? - Stack Overflow [2017-01-16]

 

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ オープンソースへ
にほんブログ村

オープンソース - ブログ村ハッシュタグ
#オープンソース



このエントリーをはてなブックマークに追加