8

データの範囲に注釈を付けるにはどうすればよいですか? たとえば、 からx = 5までのデータx = 10がカットオフよりも大きいとしたら、それをグラフに表示するにはどうすればよいでしょうか。手で注釈を付ける場合は、範囲の上に大きな括弧を描き、括弧の上に注釈を書きます。

私が見た中で最も近いのは、arrowstyle='<->'andを使用connectionstyle='bar'して、データの端を指す 2 つの矢印を、それらの尾を結ぶ線で作成することです。しかし、それは正しいことではありません。注釈用に入力したテキストは、バーの上ではなく、いずれかの矢印の下になります。

これが私の試みであり、その結果は次のとおりです。

annotate(' ', xy=(1,.5),  xycoords='data',
            xytext=(190, .5), textcoords='data',
            arrowprops=dict(arrowstyle="<->",
                            connectionstyle="bar",
                            ec="k",
                            shrinkA=5, shrinkB=5,
                            )
            )

注釈の試み

私が試みた解決策のもう 1 つの問題は、注釈ブラケットの四角い形状では、範囲を強調表示していることが実際には明確にならないことです (たとえば、中括弧とは異なります)。しかし、それは現時点ではつまらないことだと思います。

4

4 に答える 4

8

この回答で述べたように、シグモイド関数を使用して中括弧を作成できます。以下は、x 軸のすぐ上に中かっこを追加する関数です。生成される中かっこは、Figure の幅と高さが変わらない限り、軸の制限に関係なく同じに見えるはずです。

import numpy as np
import matplotlib.pyplot as plt

def draw_brace(ax, xspan, text):
    """Draws an annotated brace on the axes."""
    xmin, xmax = xspan
    xspan = xmax - xmin
    ax_xmin, ax_xmax = ax.get_xlim()
    xax_span = ax_xmax - ax_xmin
    ymin, ymax = ax.get_ylim()
    yspan = ymax - ymin
    resolution = int(xspan/xax_span*100)*2+1 # guaranteed uneven
    beta = 300./xax_span # the higher this is, the smaller the radius

    x = np.linspace(xmin, xmax, resolution)
    x_half = x[:resolution//2+1]
    y_half_brace = (1/(1.+np.exp(-beta*(x_half-x_half[0])))
                    + 1/(1.+np.exp(-beta*(x_half-x_half[-1]))))
    y = np.concatenate((y_half_brace, y_half_brace[-2::-1]))
    y = ymin + (.05*y - .01)*yspan # adjust vertical position

    ax.autoscale(False)
    ax.plot(x, y, color='black', lw=1)

    ax.text((xmax+xmin)/2., ymin+.07*yspan, text, ha='center', va='bottom')

ax = plt.gca()
ax.plot(range(10))
draw_brace(ax, (0, 8), 'large brace')
draw_brace(ax, (8, 9), 'small brace')

出力:

ここに画像の説明を入力

于 2018-11-19T22:48:42.280 に答える
5

中括弧の垂直位置を変更できるように、Jooeey の回答を変更しました。

def draw_brace(ax, xspan, yy, text):
    """Draws an annotated brace on the axes."""
    xmin, xmax = xspan
    xspan = xmax - xmin
    ax_xmin, ax_xmax = ax.get_xlim()
    xax_span = ax_xmax - ax_xmin

    ymin, ymax = ax.get_ylim()
    yspan = ymax - ymin
    resolution = int(xspan/xax_span*100)*2+1 # guaranteed uneven
    beta = 300./xax_span # the higher this is, the smaller the radius

    x = np.linspace(xmin, xmax, resolution)
    x_half = x[:int(resolution/2)+1]
    y_half_brace = (1/(1.+np.exp(-beta*(x_half-x_half[0])))
                    + 1/(1.+np.exp(-beta*(x_half-x_half[-1]))))
    y = np.concatenate((y_half_brace, y_half_brace[-2::-1]))
    y = yy + (.05*y - .01)*yspan # adjust vertical position

    ax.autoscale(False)
    ax.plot(x, y, color='black', lw=1)

    ax.text((xmax+xmin)/2., yy+.07*yspan, text, ha='center', va='bottom')
ax = plt.gca()
ax.plot(range(10))
draw_brace(ax, (0, 8), -0.5, 'large brace')
draw_brace(ax, (8, 9), 3, 'small brace')

出力:

matplotlib ブレース

また、Jooeey's answerの行に注意してください

x_half = x[:resolution/2+1]

する必要があります

x_half = x[:int(resolution/2)+1]

それ以外の場合、スクリプトがここでインデックスとして使用しようとする数値は float です。

最後に、現時点ではブレースを境界外に移動すると表示されないことに注意してください。clip_on=False次のように、パラメータを追加する必要があります。

ax.plot(x, y, color='black', lw=1, clip_on=False)
于 2020-04-27T08:18:03.480 に答える
4

すべてを関数にまとめることができます:

def add_range_annotation(ax, start, end, txt_str, y_height=.5, txt_kwargs=None, arrow_kwargs=None):
    """
    Adds horizontal arrow annotation with text in the middle

    Parameters
    ----------
    ax : matplotlib.Axes
        The axes to draw to

    start : float
        start of line

    end : float
        end of line

    txt_str : string
        The text to add

    y_height : float
        The height of the line

    txt_kwargs : dict or None
        Extra kwargs to pass to the text

    arrow_kwargs : dict or None
        Extra kwargs to pass to the annotate

    Returns
    -------
    tuple
        (annotation, text)
    """

    if txt_kwargs is None:
        txt_kwargs = {}
    if arrow_kwargs is None:
        # default to your arrowprops
        arrow_kwargs = {'arrowprops':dict(arrowstyle="<->",
                            connectionstyle="bar",
                            ec="k",
                            shrinkA=5, shrinkB=5,
                            )}

    trans = ax.get_xaxis_transform()

    ann = ax.annotate('', xy=(start, y_height),
                        xytext=(end, y_height),
                        transform=trans,
                        **arrow_kwargs)
    txt = ax.text((start + end) / 2,
                  y_height + .05,
                  txt_str,
                  **txt_kwargs)


    if plt.isinteractive():
        plt.draw()
    return ann, txt

あるいは、

start, end = .6, .8
ax.axvspan(start, end, alpha=.2, color='r')
trans = ax.get_xaxis_transform()
ax.text((start + end) / 2, .5, 'test', transform=trans)
于 2013-08-22T17:07:47.250 に答える