Format sumbu y sebagai persen

114

Saya memiliki plot yang dibuat dengan panda seperti ini:

df['myvar'].plot(kind='bar')

Sumbu y adalah format sebagai float dan saya ingin mengubah sumbu y menjadi persentase. Semua solusi yang saya temukan menggunakan sintaks ax.xyz dan saya hanya dapat menempatkan kode di bawah baris di atas yang membuat plot (saya tidak dapat menambahkan ax = ax ke baris di atas.)

Bagaimana cara memformat sumbu y sebagai persentase tanpa mengubah garis di atas?

Berikut adalah solusi yang saya temukan tetapi mengharuskan saya mendefinisikan ulang plot :

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as mtick

data = [8,12,15,17,18,18.5]
perc = np.linspace(0,100,len(data))

fig = plt.figure(1, (7,4))
ax = fig.add_subplot(1,1,1)

ax.plot(perc, data)

fmt = '%.0f%%' # Format you want the ticks, e.g. '40%'
xticks = mtick.FormatStrFormatter(fmt)
ax.xaxis.set_major_formatter(xticks)

plt.show()

Tautkan ke solusi di atas: Pyplot: menggunakan persentase pada sumbu x

Chris
sumber
Bisakah Anda mengubah jawaban yang diterima ke pendekatan yang diterapkan secara native di matplotlib? stackoverflow.com/a/36319915/1840471
Max Ghenis

Jawaban:

128

Ini terlambat beberapa bulan, tetapi saya telah membuat PR # 6251 dengan matplotlib untuk menambahkan PercentFormatterkelas baru . Dengan kelas ini Anda hanya perlu satu baris untuk memformat ulang sumbu Anda (dua jika Anda menghitung impor matplotlib.ticker):

import ...
import matplotlib.ticker as mtick

ax = df['myvar'].plot(kind='bar')
ax.yaxis.set_major_formatter(mtick.PercentFormatter())

PercentFormatter()menerima tiga argumen, xmax, decimals, symbol. xmaxmemungkinkan Anda untuk mengatur nilai yang sesuai dengan 100% pada sumbu. Ini bagus jika Anda memiliki data dari 0,0 hingga 1,0 dan Anda ingin menampilkannya dari 0% hingga 100%. Lakukan saja PercentFormatter(1.0).

Dua parameter lainnya memungkinkan Anda untuk mengatur jumlah digit setelah koma desimal dan simbol. Mereka default ke Nonedan '%', masing-masing. decimals=Noneakan secara otomatis mengatur jumlah titik desimal berdasarkan seberapa banyak sumbu yang Anda tunjukkan.

Memperbarui

PercentFormatter diperkenalkan ke Matplotlib tepat di versi 2.1.0.

Fisikawan Gila
sumber
@MateenUlhaq Harap jangan memasukkan modifikasi kode yang signifikan dalam hasil edit Anda. Anda mereplikasi kode dalam jawaban saya tanpa perlu. Itu bukan hasil edit yang bagus.
Fisikawan Gila
Saya buruk, untuk beberapa alasan aneh, saya membacanya sebagai from matplotlib.ticker import mtickdan mengasumsikan mtick"modul" telah dihapus.
Mateen Ulhaq
125

pandas dataframe plot akan mengembalikan axuntuk Anda, Dan kemudian Anda dapat mulai memanipulasi sumbu apa pun yang Anda inginkan.

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(100,5))

# you get ax from here
ax = df.plot()
type(ax)  # matplotlib.axes._subplots.AxesSubplot

# manipulate
vals = ax.get_yticks()
ax.set_yticklabels(['{:,.2%}'.format(x) for x in vals])

masukkan deskripsi gambar di sini

Jianxun Li
sumber
5
Ini akan memiliki efek yang tidak diinginkan segera setelah Anda menggeser / memperbesar / memperkecil grafik secara interaktif
hitzg
3
Jutaan kali lebih mudah daripada mencoba menggunakan matplotlib.tickerpemformat fungsi!
Jarad
Bagaimana Anda kemudian membatasi sumbu y menjadi (0,100%)? Saya mencoba ax.set_ylim (0,100) tetapi sepertinya tidak berhasil !!
mpour
@mpour hanya label yticks yang diubah, jadi batasnya masih dalam satuan alami. Pengaturan ax.set_ylim (0, 1) akan berhasil.
Joeran
79

Solusi Jianxun berhasil untuk saya tetapi merusak indikator nilai y di kiri bawah jendela.

Saya akhirnya menggunakan FuncFormattersebagai gantinya (dan juga menghapus nol tertinggal yang tidak perlu seperti yang disarankan di sini ):

import pandas as pd
import numpy as np
from matplotlib.ticker import FuncFormatter

df = pd.DataFrame(np.random.randn(100,5))

ax = df.plot()
ax.yaxis.set_major_formatter(FuncFormatter(lambda y, _: '{:.0%}'.format(y))) 

Secara umum saya akan merekomendasikan penggunaan FuncFormatteruntuk pemformatan label: dapat diandalkan, dan serbaguna.

masukkan deskripsi gambar di sini

erwanp
sumber
19
Anda dapat menyederhanakan kode bahkan lebih: ax.yaxis.set_major_formatter(FuncFormatter('{0:.0%}'.format)). AKA tidak perlu lambda, biarkan format melakukan pekerjaannya.
Daniel Himmelstein
@DanielHimmelstein, bisakah Anda menjelaskannya sedikit? Terutama di dalam {}. Tidak yakin bagaimana 0,06 saya diubah menjadi 6% menggunakan itu dengan format python. Juga solusi yang bagus. Tampaknya bekerja jauh lebih andal daripada menggunakan .set_ticklabels
DChaps
3
@DChaps '{0:.0%}'.formatmembuat fungsi pemformatan . The 0sebelum usus besar memberitahu formatter untuk menggantikan keriting kurung dan isinya dengan argumen pertama dilewatkan ke fungsi. Bagian setelah titik dua .0%,, memberi tahu pemformat cara merender nilai. The .0menentukan 0 tempat desimal dan %menspesifikasikan render sebagai persen.
Daniel Himmelstein
31

Bagi mereka yang mencari one-liner cepat:

plt.gca().set_yticklabels(['{:.0f}%'.format(x*100) for x in plt.gca().get_yticks()]) 

Atau jika Anda menggunakan Latex sebagai pemformat teks sumbu, Anda harus menambahkan satu garis miring terbalik '\'

plt.gca().set_yticklabels(['{:.0f}\%'.format(x*100) for x in plt.gca().get_yticks()]) 
np8
sumber
Bagi saya, jawaban Daniel Himmelstein berhasil sedangkan jawaban ini mengubah skalanya
R. Cox
2

Saya mengusulkan metode alternatif menggunakan seaborn

Kode kerja:

import pandas as pd
import seaborn as sns
data=np.random.rand(10,2)*100
df = pd.DataFrame(data, columns=['A', 'B'])
ax= sns.lineplot(data=df, markers= True)
ax.set(xlabel='xlabel', ylabel='ylabel', title='title')
#changing ylables ticks
y_value=['{:,.2f}'.format(x) + '%' for x in ax.get_yticks()]
ax.set_yticklabels(y_value)

masukkan deskripsi gambar di sini

Dr Arslan
sumber
0

Saya terlambat ke permainan tetapi saya baru menyadari ini: axdapat diganti dengan plt.gca()bagi mereka yang tidak menggunakan sumbu dan hanya subplot.

Menggema jawaban Fisikawan @Mad, menggunakan paket PercentFormatteritu akan menjadi:

import matplotlib.ticker as mtick

plt.gca().yaxis.set_major_formatter(mtick.PercentFormatter(1))
#if you already have ticks in the 0 to 1 range. Otherwise see their answer
Cat Mai
sumber