จัดรูปแบบแกน y เป็นเปอร์เซ็นต์


114

ฉันมีพล็อตเดิมที่สร้างขึ้นด้วยหมีแพนด้าเช่นนี้:

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

แกน y จัดรูปแบบเป็นทศนิยมและฉันต้องการเปลี่ยนแกน y เป็นเปอร์เซ็นต์ โซลูชันทั้งหมดที่ฉันพบใช้ไวยากรณ์ ax.xyz และฉันสามารถวางโค้ดใต้บรรทัดด้านบนที่สร้างพล็อตได้เท่านั้น (ฉันไม่สามารถเพิ่ม ax = ax ในบรรทัดด้านบนได้)

ฉันจะจัดรูปแบบแกน y เป็นเปอร์เซ็นต์โดยไม่ต้องเปลี่ยนบรรทัดด้านบนได้อย่างไร

นี่คือวิธีแก้ปัญหาที่ฉันพบแต่ต้องการให้ฉันกำหนดพล็อตใหม่ :

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()

ลิงก์ไปยังโซลูชันด้านบน: Pyplot: ใช้เปอร์เซ็นต์บนแกน x


คุณช่วยเปลี่ยนคำตอบที่ยอมรับของคุณเป็นแนวทางที่นำมาใช้ใน matplotlib ได้ไหม stackoverflow.com/a/36319915/1840471
Max Ghenis

คำตอบ:


130

นี่ช้าไปสองสามเดือน แต่ฉันได้สร้างPR # 6251ด้วย matplotlib เพื่อเพิ่มPercentFormatterคลาสใหม่ ด้วยคลาสนี้คุณต้องใช้บรรทัดเดียวเพื่อจัดรูปแบบแกนของคุณใหม่ (สองบรรทัดถ้าคุณนับการนำเข้าmatplotlib.ticker):

import ...
import matplotlib.ticker as mtick

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

PercentFormatter()xmaxยอมรับสามข้อโต้แย้ง decimals, symbol, xmaxให้คุณตั้งค่าที่สอดคล้องกับ 100% บนแกน นี่เป็นสิ่งที่ดีถ้าคุณมีข้อมูลตั้งแต่ 0.0 ถึง 1.0 และคุณต้องการแสดงข้อมูลตั้งแต่ 0% ถึง 100% PercentFormatter(1.0)เพียงแค่ทำ

พารามิเตอร์อีกสองตัวช่วยให้คุณกำหนดจำนวนหลักหลังจุดทศนิยมและสัญลักษณ์ได้ ค่าเริ่มต้นเป็นNoneและ'%'ตามลำดับ decimals=Noneจะกำหนดจำนวนจุดทศนิยมโดยอัตโนมัติตามจำนวนแกนที่คุณแสดง

อัปเดต

PercentFormatter ได้รับการแนะนำให้รู้จักกับ Matplotlib ในเวอร์ชัน 2.1.0


@MateenUlhaq โปรดอย่าแนะนำการแก้ไขโค้ดที่สำคัญในการแก้ไขของคุณ คุณจำลองรหัสในคำตอบของฉันโดยไม่จำเป็น มันไม่ใช่การแก้ไขที่ดี
Mad Physicist

ฉันไม่ดีด้วยเหตุผลแปลก ๆ ฉันอ่านfrom matplotlib.ticker import mtickและสันนิษฐานว่าmtick"โมดูล" ถูกลบออก
Mateen Ulhaq

125

แผนภาพดาต้าเฟรมของแพนด้าจะคืนค่าaxให้คุณจากนั้นคุณสามารถเริ่มจัดการแกนตามที่คุณต้องการได้

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])

ใส่คำอธิบายภาพที่นี่


5
สิ่งนี้จะมีผลกระทบที่ไม่ต้องการทันทีที่คุณแพน / ซูมกราฟแบบโต้ตอบ
hitzg

3
ง่ายกว่าการพยายามใช้matplotlib.tickerฟอร์แมตของฟังก์ชันเป็นล้านเท่า!
Jarad

แล้วคุณจะ จำกัด แกน y ให้พูดได้อย่างไร (0,100%)? ฉันลอง ax.set_ylim (0,100) แต่ดูเหมือนจะไม่ได้ผล !!
mpour

@mpour มีการเปลี่ยนแปลงเฉพาะป้ายกำกับของ yticks ดังนั้นขีด จำกัด ยังคงอยู่ในหน่วยธรรมชาติ การตั้งค่า ax.set_ylim (0, 1) จะทำเคล็ดลับ
Joeran

80

วิธีแก้ปัญหาของJianxunได้ผลสำหรับฉัน แต่ตัวบ่งชี้ค่า y ที่ด้านล่างซ้ายของหน้าต่างพัง

ฉันลงเอยด้วยการใช้FuncFormatterแทน (และถอดศูนย์ต่อท้ายที่ไม่จำเป็นออกตามที่แนะนำไว้ที่นี่ ):

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))) 

โดยทั่วไปฉันขอแนะนำให้ใช้FuncFormatterสำหรับการจัดรูปแบบฉลาก: เชื่อถือได้และหลากหลาย

ใส่คำอธิบายภาพที่นี่


19
ax.yaxis.set_major_formatter(FuncFormatter('{0:.0%}'.format))คุณสามารถลดความซับซ้อนของรหัสมากขึ้น: AKA ไม่จำเป็นต้องใช้แลมด้าให้ฟอร์แมตทำงาน
Daniel Himmelstein

@DanielHimmelstein ช่วยอธิบายเรื่องนี้หน่อยได้ไหม โดยเฉพาะภายใน {} ไม่แน่ใจว่า 0.06 ของฉันเปลี่ยนเป็น 6% ได้อย่างไรโดยใช้รูปแบบ python ยังเป็นทางออกที่ดี ดูเหมือนว่าจะทำงานได้อย่างน่าเชื่อถือมากกว่าการใช้. set_ticklabels
DChaps

3
@DChaps '{0:.0%}'.formatสร้างฟังก์ชั่นการจัดรูปแบบ 0ก่อนลำไส้ใหญ่บอก formatter เพื่อแทนที่ผมหยิกวงเล็บและเนื้อหาที่มีอาร์กิวเมนต์แรกส่งผ่านไปยังฟังก์ชั่น ส่วนหลังเครื่องหมายทวิภาค.0%จะบอกผู้จัดรูปแบบว่าจะแสดงค่าอย่างไร .0ระบุ 0 ตำแหน่งทศนิยมและ%ระบุการแสดงผลเป็นเปอร์เซ็นต์
Daniel Himmelstein

31

สำหรับผู้ที่กำลังมองหาซับในฉบับย่อ:

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

หรือถ้าคุณใช้Latexเป็นตัวจัดรูปแบบข้อความแกนคุณต้องเพิ่มแบ็กสแลช '\' หนึ่งตัว

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

สำหรับฉันคำตอบของ Daniel Himmelstein ได้ผลในขณะที่คำตอบนี้เปลี่ยนมาตราส่วน
R.Cox

2

ฉันเสนอวิธีอื่นโดยใช้ seaborn

รหัสการทำงาน:

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)

ใส่คำอธิบายภาพที่นี่


0

ฉันเล่นเกมช้า แต่ฉันเพิ่งรู้สิ่งนี้: axสามารถถูกแทนที่ด้วยplt.gca()สำหรับผู้ที่ไม่ได้ใช้แกนและเพียงแค่พล็อตย่อย

คำตอบ Echoing @Mad Physicist โดยใช้แพ็คเกจPercentFormatterจะเป็น:

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.