matplotlib 막대 차트에 값 레이블 추가
비교적 쉬울 것 같은 느낌이 들었습니다. 아래에 가져온 코드는 내가 작업중인 더 큰 프로젝트를 기반으로 한 샘플입니다. 모든 세부 정보를 게시 할 이유가 없었으므로 가져온 데이터 구조를 그대로 수락하십시오.
기본적으로 막대 차트를 만들고 있으며 막대에 값 레이블을 추가하는 방법을 알아낼 수 있습니다 (막대 중앙 또는 바로 위). 웹에서 샘플을 살펴 보았지만 내 코드를 성공적으로 구현하지 못했습니다. 나는 해결책이 '텍스트'또는 '주석'이라고 믿지만 나는 : 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
축 반환 하지 인물 그래서 좀 더 내 대답을 내가 그것을 참조하기 위해 당신의 주어진 코드를 변경했습니다 취소 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')
이렇게하면 다음과 같은 레이블이 지정된 플롯이 생성됩니다.
다른 질문에 대한이 답변 에서 언급 된 기능을 기반 으로 막대 차트에 레이블을 배치하는 데 매우 일반적으로 적용 가능한 솔루션을 찾았습니다.
안타깝게도 다른 솔루션은 레이블과 막대 사이의 간격이 막대의 절대 단위로 지정 되거나 막대 높이에 따라 조정 되기 때문에 많은 경우에서 작동하지 않습니다 . 전자는 좁은 범위의 값에 대해서만 작동하고 후자는 한 플롯 내에서 일관되지 않은 간격을 제공합니다. 둘 다 로그 축에서는 잘 작동하지 않습니다.
내가 제안한 솔루션은 스케일 (즉, 작은 숫자와 큰 숫자)과는 독립적으로 작동 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")
막대 위에 데이터 포인트 만 추가하려는 경우 다음을 사용하여 쉽게 수행 할 수 있습니다.
for i in range(len(frequencies)): # your number of bars
plt.text(x = x_values[i]-0.25, #takes your x values as horizontal positioning argument
y = y_values[i]+1, #takes your y values as vertical positioning argument
s = data_labels[i], # the labels you want to add to the data
size = 9) # font size of datalabels
참고 URL : https://stackoverflow.com/questions/28931224/adding-value-labels-on-a-matplotlib-bar-chart
'Programing' 카테고리의 다른 글
Redirect() vs RedirectPermanent() in ASP.NET MVC (0) | 2020.11.01 |
---|---|
방랑 쉘 프로 비 저너에 환경 변수 전달 (0) | 2020.11.01 |
각 단어의 첫 글자를 얻다 (0) | 2020.10.31 |
SBT는 로컬 Maven 저장소에서 파일을 찾지 못합니다. (0) | 2020.10.31 |
Java에서 개체 복제 (0) | 2020.10.31 |