

matplotlibを使っています。どうしたらグラフのピクセル座標が得られるでしょうか。  
x,y軸が実数の場合には、  
ax.transData.transformを使ってピクセル座標が得られることは分かりました。  
しかしx座標がpd.Timestampの時はうまくいきません。  
どうしたら時系列データのグラフでピクセル座標が得られるでしょうか。


CC BY-SA 4.0
2018-06-07T13:27:06.737
44600
2018-06-10T08:40:42.473
2018-06-10T08:30:51.943
15171
28823
question
python matplotlib
matplotlibの時系列グラフに図、文字、注釈等を入れる方法


日付と時刻を扱うのに、Pythonでは`datetime`を使いますが、Matplotlibでは、独自の
`matplotlib.dates`を使います。`matplotlib.dates`は、西暦1年1月1日からの日数プラス1の浮動小数点数で表します。例えば、`0001-01-01
06:00`は、`1.25`になります。

また、`matplotlib.dates`と`datetime`を変換するためのヘルパー関数があります。`date2num`を使うと、`datetime`オブジェクトを`Matplotlib.dates`に変換できます。逆の変換には、`num2date`を使います。

マニュアル [matplotlib.dates](https://matplotlib.org/api/dates_api.html)

`matplotlib.dates`を使うと、ax.transData.transformを使ってピクセル座標を取得することができます。以下は、Motplotlib
の [Transformations
Tutorial](https://matplotlib.org/tutorials/advanced/transforms_tutorial.html#sphx-
glr-tutorials-advanced-transforms-tutorial-py) のサンプルを時系列のものに変えたものです。

[code]

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    from matplotlib.dates import date2num
    from datetime import datetime
    
    x = pd.date_range('2018-06-01', '2018-06-11', freq='1H')
    y = x.map(lambda p: p.toordinal())
    
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot_date(x, y)
    
    xdata = date2num(datetime(2018, 6, 5))
    ydata = xdata
    xdisplay, ydisplay = ax.transData.transform_point((xdata, ydata))
    
    bbox = dict(boxstyle="round", fc="0.8")
    arrowprops = dict(
        arrowstyle="->",
        connectionstyle="angle,angleA=0,angleB=90,rad=10")
    
    offset = 72
    ax.annotate('data = (%.1f, %.1f)' % (xdata, ydata),
            (xdata, ydata), xytext=(-2*offset, offset), textcoords='offset points',
            bbox=bbox, arrowprops=arrowprops)
    
    disp = ax.annotate('display = (%.1f, %.1f)' % (xdisplay, ydisplay),
                   (xdisplay, ydisplay), xytext=(0.5*offset, -offset),
                   xycoords='figure pixels',
                   textcoords='offset points',
                   bbox=bbox, arrowprops=arrowprops)
    
    plt.show()
    
[/code]

[![画像の説明をここに入力](https://i.stack.imgur.com/UMRKW.png)](https://i.stack.imgur.com/UMRKW.png)

上のサンプルのように、時系列のグラフに図形、文字、注釈等を入れることは`ax.transData.transform`を使わなくてもできます。Matplotlibのマニュアルには、95%のケースでは`transform`を使う必要がないと書かれています。

また、ax.transData.transform を GUI で使った場合には、位置がずれますが、原因と対応については[Transformations
Tutorial](https://matplotlib.org/tutorials/advanced/transforms_tutorial.html#sphx-
glr-tutorials-advanced-transforms-tutorial-
py)の方に説明があります。ピクセル座標系への変換を使うのは手間が相当必要なので普通は使わないほうがいいでしょう。

なお、`datetime.toordinal()`は、日付部分のみの変換なので常に整数になりますが、午前0時の場合には、`matplotlib.dates`と同じ値です。


CC BY-SA 4.0
2018-06-09T16:02:21.470
44651
2018-06-10T08:40:42.473
2018-06-10T08:40:42.473
15171
15171
44600
answer