Saya terjebak pada sesuatu yang rasanya relatif mudah. Kode yang saya bawa di bawah ini adalah contoh berdasarkan proyek yang lebih besar yang sedang saya kerjakan. Saya tidak melihat alasan untuk memposting semua detail, jadi terimalah struktur data yang saya bawa apa adanya.
Pada dasarnya, saya membuat diagram batang, dan saya hanya bisa mengetahui cara menambahkan label nilai pada batang (di tengah batang, atau tepat di atasnya). Telah melihat sampel di seluruh web tetapi tidak berhasil menerapkan kode saya sendiri. Saya percaya solusinya adalah dengan 'teks' atau 'anotasi', tetapi saya: a) tidak tahu mana yang akan digunakan (dan secara umum, belum tahu kapan harus menggunakan yang mana). b) tidak dapat melihat untuk menyajikan label nilai. Sangat menghargai bantuan Anda, kode saya di bawah ini. Terima kasih sebelumnya!
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)
sumber
Jawaban:
Pertama
freq_series.plot
mengembalikan sumbu bukan gambar jadi untuk membuat jawaban saya sedikit lebih jelas, saya telah mengubah kode yang Anda berikan untuk merujuknyaax
daripadafig
lebih konsisten dengan contoh kode lainnya.Anda bisa mendapatkan daftar batang yang diproduksi di plot dari
ax.patches
anggota. Kemudian Anda dapat menggunakan teknik yang ditunjukkan dalam contoh galeri inimatplotlib
untuk menambahkan label menggunakanax.text
metode tersebut.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')
Ini menghasilkan plot berlabel yang terlihat seperti:
sumber
text
hanya mencetak beberapa teks ke plot, sementaraannotate
merupakan helper yang dapat Anda gunakan untuk dengan mudah juga menambahkan panah dari teks yang menunjuk ke titik tertentu pada plot yang dirujuk oleh teks.Berdasarkan fitur yang disebutkan dalam jawaban untuk pertanyaan lain ini, saya telah menemukan solusi yang dapat diterapkan secara umum untuk menempatkan label pada diagram batang.
Sayangnya, solusi lain tidak berfungsi dalam banyak kasus, karena jarak antara label dan batang ditentukan dalam satuan absolut batang atau diskalakan dengan ketinggian batang . Yang pertama hanya berfungsi untuk rentang nilai yang sempit dan yang terakhir memberikan jarak yang tidak konsisten dalam satu plot. Tidak ada yang bekerja dengan baik dengan sumbu logaritmik.
Solusi yang saya usulkan bekerja secara independen dari skala (yaitu untuk bilangan kecil dan besar) dan bahkan menempatkan label dengan benar untuk nilai negatif dan dengan skala logaritmik karena menggunakan unit visual
points
untuk offset.Saya telah menambahkan angka negatif untuk menunjukkan penempatan label yang benar dalam kasus seperti itu.
Nilai ketinggian setiap batang digunakan sebagai label untuk itu. Label lain dapat dengan mudah digunakan dengan potongan Simon
for rect, label in zip(rects, labels)
.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")
Sunting: Saya telah mengekstrak fungsionalitas yang relevan dalam suatu fungsi, seperti yang disarankan oleh barnhillec .
Ini menghasilkan keluaran sebagai berikut:
Dan dengan skala logaritmik (dan beberapa penyesuaian pada data masukan untuk menampilkan penskalaan logaritmik), inilah hasilnya:
sumber
Berdasarkan jawaban di atas (hebat!), Kita juga dapat membuat plot batang horizontal hanya dengan beberapa penyesuaian:
# 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")
sumber
freq_series.plot(kind='barh', grid=True)
ax.set_xlim([0, 1.1*max_value])
Jika Anda hanya ingin memberi label titik data di atas bilah, Anda bisa menggunakan plt.annotate ()
Kode saya:
import numpy as np import matplotlib.pyplot as plt n = [1,2,3,4,5,] s = [i**2 for i in n] line = plt.bar(n,s) plt.xlabel('Number') plt.ylabel("Square") for i in range(len(s)): plt.annotate(str(s[i]), xy=(n[i],s[i]), ha='center', va='bottom') plt.show()
Dengan menentukan perataan horizontal dan vertikal
'center'
dan'bottom'
masing - masing dapat memperoleh anotasi di tengah.sumber
Jika Anda hanya ingin menambahkan Titik Data di atas bilah, Anda dapat dengan mudah melakukannya dengan:
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
sumber