私は比較的簡単だと思うような何かにこだわった。以下に示すコードは、私が取り組んでいるより大きなプロジェクトに基づいたサンプルです。すべての詳細を投稿する理由はありませんでしたので、私が持ってきたデータ構造をそのまま受け入れてください。
基本的に、私は棒グラフを作成していますが、棒に値ラベルを追加する方法を見つけることができます(棒の中央またはそのすぐ上)。 Web上のサンプルを調べていますが、自分のコードで実装できませんでした。私は解決策が「テキスト」または「注釈」のいずれかであると信じていますが、私は:a)どちらを使用するのかわかりません(一般的に言えば、どちらをいつ使用するのかわかりません)。 b)値ラベルを提示するためにどちらを取得するかを見ることができません。あなたの助け、下の私のコードに感謝します。前もって感謝します!
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
pd.set_option('display.mpl_style', 'default')
%matplotlib inline
# Bring some raw data.
frequencies = [6, 16, 75, 160, 244, 260, 145, 73, 16, 4, 1]
# In my original code I create a series and run on that,
# so for consistency I create a series from the list.
freq_series = pd.Series.from_array(frequencies)
x_labels = [108300.0, 110540.0, 112780.0, 115020.0, 117260.0, 119500.0,
121740.0, 123980.0, 126220.0, 128460.0, 130700.0]
# Plot the figure.
plt.figure(figsize=(12, 8))
fig = freq_series.plot(kind='bar')
fig.set_title('Amount Frequency')
fig.set_xlabel('Amount ($)')
fig.set_ylabel('Frequency')
fig.set_xticklabels(x_labels)
最初にfreq_series.plot
は軸を返しますnot数字をより明確にするために、特定のコードを変更して、それをax
として参照するようにしましたfig
は、他のコード例との一貫性を高めます。
ax.patches
メンバーからプロットで生成されたバーのリストを取得できます。次に、 このmatplotlib
ギャラリーの例 で示した手法を使用して、 ax.text
メソッドを使用してラベルを追加できます。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# Bring some raw data.
frequencies = [6, 16, 75, 160, 244, 260, 145, 73, 16, 4, 1]
# In my original code I create a series and run on that,
# so for consistency I create a series from the list.
freq_series = pd.Series.from_array(frequencies)
x_labels = [108300.0, 110540.0, 112780.0, 115020.0, 117260.0, 119500.0,
121740.0, 123980.0, 126220.0, 128460.0, 130700.0]
# Plot the figure.
plt.figure(figsize=(12, 8))
ax = freq_series.plot(kind='bar')
ax.set_title('Amount Frequency')
ax.set_xlabel('Amount ($)')
ax.set_ylabel('Frequency')
ax.set_xticklabels(x_labels)
rects = ax.patches
# Make some labels.
labels = ["label%d" % i for i in xrange(len(rects))]
for rect, label in Zip(rects, labels):
height = rect.get_height()
ax.text(rect.get_x() + rect.get_width() / 2, height + 5, label,
ha='center', va='bottom')
これにより、次のようなラベル付きプロットが生成されます。
別の質問に対するこの回答 に記載されている機能に基づいて、棒グラフにラベルを配置するための非常に一般的に適用可能なソリューションを見つけました。
残念ながら、ラベルとバーの間隔は バーの絶対単位で指定 または バーの高さでスケーリング であるため、他の解決策は多くの場合機能しません。前者は狭い範囲の値に対してのみ機能し、後者は1つのプロット内で一貫性のない間隔を与えます。どちらも対数軸ではうまく機能しません。
私が提案する解決策は、スケールに関係なく(つまり、小さい数と大きい数に)機能し、負の値と対数目盛のラベルを正しく配置します。これは、オフセットに視覚単位points
を使用するためです.
そのような場合のラベルの正しい配置を示すために、負の数を追加しました。
各バーの高さの値は、そのラベルとして使用されます。他のラベルは Simonのfor rect, label in Zip(rects, labels)
snippet で簡単に使用できます。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# Bring some raw data.
frequencies = [6, -16, 75, 160, 244, 260, 145, 73, 16, 4, 1]
# In my original code I create a series and run on that,
# so for consistency I create a series from the list.
freq_series = pd.Series.from_array(frequencies)
x_labels = [108300.0, 110540.0, 112780.0, 115020.0, 117260.0, 119500.0,
121740.0, 123980.0, 126220.0, 128460.0, 130700.0]
# Plot the figure.
plt.figure(figsize=(12, 8))
ax = freq_series.plot(kind='bar')
ax.set_title('Amount Frequency')
ax.set_xlabel('Amount ($)')
ax.set_ylabel('Frequency')
ax.set_xticklabels(x_labels)
def add_value_labels(ax, spacing=5):
"""Add labels to the end of each bar in a bar chart.
Arguments:
ax (matplotlib.axes.Axes): The matplotlib object containing the axes
of the plot to annotate.
spacing (int): The distance between the labels and the bars.
"""
# For each bar: Place a label
for rect in ax.patches:
# Get X and Y placement of label from rect.
y_value = rect.get_height()
x_value = rect.get_x() + rect.get_width() / 2
# Number of points between bar and label. Change to your liking.
space = spacing
# Vertical alignment for positive values
va = 'bottom'
# If value of bar is negative: Place label below bar
if y_value < 0:
# Invert space to place label below
space *= -1
# Vertically align label at top
va = 'top'
# Use Y value as label and format number with one decimal place
label = "{:.1f}".format(y_value)
# Create annotation
ax.annotate(
label, # Use `label` as label
(x_value, y_value), # Place label at end of the bar
xytext=(0, space), # Vertically shift label by `space`
textcoords="offset points", # Interpret `xytext` as offset in points
ha='center', # Horizontally center label
va=va) # Vertically align label differently for
# positive and negative values.
# Call the function above. All the magic happens there.
add_value_labels(ax)
plt.savefig("image.png")
編集: barnhillec 。で示唆されているように、関数の関連機能を抽出しました
これにより、次の出力が生成されます。
対数目盛(および対数目盛を示すための入力データの調整)を使用すると、次のようになります。
上記の(すばらしい!)答えを基に、わずかな調整で水平棒グラフを作成することもできます。
# Bring some raw data.
frequencies = [6, -16, 75, 160, 244, 260, 145, 73, 16, 4, 1]
freq_series = pd.Series(frequencies)
y_labels = [108300.0, 110540.0, 112780.0, 115020.0, 117260.0, 119500.0,
121740.0, 123980.0, 126220.0, 128460.0, 130700.0]
# Plot the figure.
plt.figure(figsize=(12, 8))
ax = freq_series.plot(kind='barh')
ax.set_title('Amount Frequency')
ax.set_xlabel('Frequency')
ax.set_ylabel('Amount ($)')
ax.set_yticklabels(y_labels)
ax.set_xlim(-40, 300) # expand xlim to make labels easier to read
rects = ax.patches
# For each bar: Place a label
for rect in rects:
# Get X and Y placement of label from rect.
x_value = rect.get_width()
y_value = rect.get_y() + rect.get_height() / 2
# Number of points between bar and label. Change to your liking.
space = 5
# Vertical alignment for positive values
ha = 'left'
# If value of bar is negative: Place label left of bar
if x_value < 0:
# Invert space to place label to the left
space *= -1
# Horizontally align label at right
ha = 'right'
# Use X value as label and format number with one decimal place
label = "{:.1f}".format(x_value)
# Create annotation
plt.annotate(
label, # Use `label` as label
(x_value, y_value), # Place label at end of the bar
xytext=(space, 0), # Horizontally shift label by `space`
textcoords="offset points", # Interpret `xytext` as offset in points
va='center', # Vertically center label
ha=ha) # Horizontally align label differently for
# positive and negative values.
plt.savefig("image.png")