Matplotlibでマイナス記号が短くなる？見た目を整える一手間

## はじめに

[matplotlib](https://matplotlib.org/)でグラフ作りの終盤を迎えたとき、  
軸ラベルをちょっとカスタムしたくなりますよね？

ただ、たとえば目盛りの符号を手動で入れ直したりすると、  
下の図のように、ASCIIのハイフン（-）で短く化けて表示されてしまうんですよね。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599258/73c4e657-1324-4bb4-9785-f28b03aa2b30.png" width="40%">

本当は目盛りにはUnicodeマイナスを使いたい派なのですが、
その一手間って地味に大変で……  
「後回しにしたい気持ち」と「やっぱりシャキッとしたい気持ち」が、いつも頭の中でせめぎ合います。

<br>

この記事では、**Unicodeのマイナス記号（&#8722;）** を使って、  
**たったひと手間で印象が変わる**、そんな可視化の工夫を紹介します。


## 原因

Pythonで使われる `-` は、実はASCIIのハイフン（U+002D）で、数学的なマイナス記号とは異なる文字です。

一方、Unicodeのマイナス記号（U+2212）は、数式やグラフでの見た目が美しくなるように設計されています。

以下に、両者の違いを簡単にまとめてみました。

| 表示 | 記法                               | 名前           | Unicode |
|------|------------------------------------|----------------|---------|
| -    | `"-"` または `"\u002D"`            | HYPHEN-MINUS   | U+002D  |
| &#8722; | `"\N{MINUS SIGN}"` または `"\u2212"` | MINUS SIGN     | U+2212  |


## Pythonコードで符号の種類を確認

以下のコードでは、ASCIIのハイフン (-, U+002D) と Unicodeのマイナス記号 (&#8722;, U+2212) の違いを `unicodedata` モジュールを使って確認しています。  
それぞれの記号がどんな名前で登録されていて、コードポイントがどう違うのかが表示されます。  
また、実際に `==` で比較して、**同じ文字かどうかも検証**しています。

```python
import unicodedata

# ASCIIのハイフン（Hyphen-Minus）
hyphen_minus_1 = "-"
hyphen_minus_2 = "\u002D"

# Unicodeのマイナス記号（Minus Sign）
uni_minus_1 = "\N{MINUS SIGN}"
uni_minus_2 = "\u2212"

# 表示して比較
for label, char in [
    ("hyphen_minus_1", hyphen_minus_1),
    ("hyphen_minus_2", hyphen_minus_2),
    ("uni_minus_1", uni_minus_1),
    ("uni_minus_2", uni_minus_2),
]:
    print(f"{label} = '{char}' | name: {unicodedata.name(char)} | codepoint: U+{ord(char):04X}")

# 比較結果の確認
print("\nEquality check:")
print("hyphen_minus_1 == hyphen_minus_2 →", hyphen_minus_1 == hyphen_minus_2)
print("uni_minus_1 == uni_minus_2       →", uni_minus_1 == uni_minus_2)
print("hyphen_minus_1 == uni_minus_1    →", hyphen_minus_1 == uni_minus_1)
```

**出力結果**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599258/19dd4d07-6d20-4faa-947f-fdf97ec4359c.png)
>（※ Markdownのコードブロック内では、- と &#8722; の見た目の違いがフォントによって崩れることがあります。ここではスクリーンショットで表示しています。）

この結果から、見た目が似ていても、異なるUnicode文字として扱われていることがわかります。


## MatplotlibでUnicodeマイナス記号の使用例

実際のコードで、matplotlibのx軸のticksラベルの符号を入れ替えてUnicodeのマイナス記号を適用してみます。

```python
import matplotlib.pyplot as plt
import numpy as np


x = np.linspace(-1.5, 1.5, 100)
y = x**3

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

# U+2212（数式用のマイナス）
# uni_minus = \u2212 でも可
uni_minus = "\N{MINUS SIGN}"

# x軸の描画範囲だけを使う
xmin, xmax = ax.get_xlim()
xticks = ax.get_xticks()
visible_xticks = [x for x in xticks if xmin <= x <= xmax]

# 符号の反転（−を明示）
xticklabels = [
    f"{uni_minus}{abs(x)}" if x > 0 else abs(x)
    for x in visible_xticks
]

ax.set_xticks(visible_xticks)
ax.set_xticklabels(xticklabels)

# 視線をx軸に集中させるため
ax.set_yticks([])

plt.title("Unicode Minus on X-axis")
plt.show()
```
**出力結果**（X軸の目盛りラベルの反転）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599258/5c2064e3-aa9e-4a17-a1f4-00dac2646970.png)

軸目盛りの符号を手動で反転しても美しいことがわかりますね！

<br>

<details><summary>元グラフ、Unicode, ASCII Hyphenマイナスの結果を比較してみる</summary>


| 元グラフ | Unicode | ASCII Hyphen |
|:-:|:-:|:-:|
| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599258/d2c5c7da-8f2a-488a-b739-66c1bbdfb29f.png) | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599258/5c2064e3-aa9e-4a17-a1f4-00dac2646970.png) | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1599258/5cb0db4d-20fb-49b0-944b-1393b03edc07.png)  |

(サンプルコードはGogle Colab[こちら](https://colab.research.google.com/drive/1bTpvwvxu7IxQJJbHA2IU-PSYsFyFXee1?usp=sharing)から閲覧できます。)

Unicodeのマイナス記号（&#8722;）は、ハイフンが長く、元グラフと同じ見た目になります。
一方、軸目盛りを通常の方法で編集すると、ASCIIのハイフン（-）が使われるため、マイナス記号が短く表示されてしまうのがわかると思います。

</details>


## まとめ

この記事では、matplotlibでラベルをカスタムしたときに、  
ハイフンが表示されてしまう原因と、その解決方法について紹介しました。

ハイフンは電話番号では馴染み深いけど、  
グラフに出てくると……ちょっとそこは察してほしい、なんて思ってしまいますよね。  
でもこういうのって、コードの中で自動的に処理されてるから、  
ちゃんと直そうと思ったら、意識して手を加えないとできないんですよね。

<br>

あの縮こまった“マイナスのシワ”を、  
シャキッと引き伸ばすような。  
そんな手助けができたのなら——心から嬉しく思います。


## 参考

- [Matplotlib公式：Unicode minusとASCII hyphenの違い](https://matplotlib.org/stable/gallery/text_labels_and_annotations/unicode_minus.html)
- [Unicode minus: U+2212](https://www.compart.com/en/unicode/U+2212)
-  [ASCII hyphen: U+002D](https://www.compart.com/en/unicode/U+002D)