Відформатуйте вісь y у відсотках


114

У мене є існуючий сюжет, який створили з такими пандами:

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

Вісь y має формат як float, і я хочу змінити вісь 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
Макс Ghenis

Відповіді:


128

На це на кілька місяців пізніше, але я створив 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 Будь ласка, не вводьте значні зміни коду у свої зміни. Ви повторили код у моїй відповіді без потреби. Це було не гарне редагування.
Божевільний фізик

Мій поганий, я з якихось дивних причин прочитав, що як 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
Це матиме небажані ефекти, як тільки ви інтерактивно
пануєте / наближаєте

3
У мільйон разів простіше, ніж намагатися використовувати matplotlib.tickerфункціональні формати!
Джарад

Як ви обмежите вісь y, щоб сказати (0,100%)? Я спробував ax.set_ylim (0,100), але це, здається, не працює !!
mpour

@mpour змінюються лише мітки ярликів, тому обмеження все ще знаходяться в натуральних одиницях. Встановлення ax.set_ylim (0, 1) зробить свою справу.
Джоеран

79

Рішення 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 не потрібна лямбда, нехай формат виконує роботу.
Даніель Хіммельштайн

@DanielHimmelstein чи можете ви це трохи пояснити? Особливо всередині {}. Не впевнений, як мій 0,06 перетворюється на 6%, використовуючи формат python. Також чудове рішення. Здається, працює набагато надійніше, ніж використовувати .set_ticklabels
DChaps

3
@DChaps '{0:.0%}'.formatстворює функцію форматування . 0Перед двокрапкою говорить форматіровщіку замінити фігурні дужки і його вміст з першим аргументом , переданої функцією. Частина після двокрапки, .0%повідомляє форматові, як віднести значення. .0Вказує 0 знаків після коми і %визначає , рендеринга в процентах.
Даніель Гіммельштайн

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

Для мене відповідь Даніеля Гіммельштайна спрацювала, тоді як ця відповідь змінила шкалу
Р. Кокс

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()тим, хто не використовує оси та просто субплоти.

Відповідь фізики @Mad, використовуючи пакет, 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.