Как построить временные метки ЧЧ: ММ на Python Matplotlib "Clock" Polar Plot - PullRequest
0 голосов
/ 02 июня 2019

Я пытаюсь построить данные о кормлении млекопитающих в моменты времени на полярной диаграмме. В приведенном ниже примере есть только один день, но каждый день в конечном итоге будет нанесен на один и тот же график (через разные оси). В настоящее время у меня есть вся эстетика, но мои данные отображаются неправильно. Как заставить часы правильно строить график?

Я предполагаю, что решение, скорее всего, связано с pd.datetime и np.deg2rad, но я не нашел правильную комбинацию.

Я импортирую свои данные из csv и фильтрую каждый день на основе следующей даты:

#Filtered portion:
Day1 = df[df.Day == '5/22']

Это дает мне следующие данные:

    Day   Time  Feeding_Quality    Feed_Num
0  5/22  16:15            G        2
1  5/22  19:50            G        2
2  5/22  20:15            G        2
3  5/22  21:00            F        1
4  5/22  23:30            G        2

Вот код:

fig = plt.figure(figsize=(7,7))

ax = plt.subplot(111, projection = 'polar')

ax.bar(Day1['Time'], Day1['Feed_Num'], width = 0.1, alpha=0.3, color='red', label='Day 1')

# Make the labels go clockwise
ax.set_theta_direction(-1)

#Place Zero at Top
ax.set_theta_offset(np.pi/2)

#Set the circumference ticks
ax.set_xticks(np.linspace(0, 2*np.pi, 24, endpoint=False))

# set the label names
ticks = ['12 AM', '1 AM', '2 AM', '3 AM', '4 AM', '5 AM', '6 AM', '7 AM','8 AM','9 AM','10 AM','11 AM','12 PM', '1 PM', '2 PM', '3 PM', '4 PM',  '5 PM', '6 PM', '7 PM', '8 PM', '9 PM', '10 PM', '11 PM' ]
ax.set_xticklabels(ticks)

# suppress the radial labels
plt.setp(ax.get_yticklabels(), visible=False)

#Bars to the wall
plt.ylim(0,2)

plt.legend(bbox_to_anchor=(1,0), fancybox=True, shadow=True)
plt.show()

Как можно догадаться из данных, все построенные бары были бы во второй половине дня, но, как видно из вывода графика, данные повсюду.

polar clock plot

1 Ответ

1 голос
/ 03 июня 2019
import numpy as np
from matplotlib import pyplot as plt
import datetime
df = pd.DataFrame({'Day': {0: '5/22', 1: '5/22', 2: '5/22', 3: '5/22', 4: '5/22'},
                   'Time': {0: '16:15', 1: '19:50', 2: '20:15', 3: '21:00', 4: '23:30'},
                   'Feeding_Quality': {0: 'G', 1: 'G', 2: 'G', 3: 'F', 4: 'G'},
                   'Feed_Num': {0: 2, 1: 2, 2: 2, 3: 1, 4: 2}})

Создать серию объектов datetime.datetime из столбца 'Time'; преобразовать это в процентах от 24 часов; превратить это в радианы.

xs = pd.to_datetime(df['Time'],format= '%H:%M' )
xs = xs - datetime.datetime.strptime('00:00:00', '%H:%M:%S')
xs = xs.dt.seconds / (24 * 3600)
xs = xs * 2 * np.pi

Используйте это в качестве x значений для графика

fig = plt.figure(figsize=(7,7))
ax = plt.subplot(111, projection = 'polar')
ax.bar(xs, df['Feed_Num'], width = 0.1, alpha=0.3, color='red', label='Day 1')

# Make the labels go clockwise
ax.set_theta_direction(-1)

#Place Zero at Top
ax.set_theta_offset(np.pi/2)

#Set the circumference ticks
ax.set_xticks(np.linspace(0, 2*np.pi, 24, endpoint=False))

# set the label names
ticks = ['12 AM', '1 AM', '2 AM', '3 AM', '4 AM', '5 AM', '6 AM', '7 AM','8 AM','9 AM','10 AM','11 AM','12 PM', '1 PM', '2 PM', '3 PM', '4 PM',  '5 PM', '6 PM', '7 PM', '8 PM', '9 PM', '10 PM', '11 PM' ]
ax.set_xticklabels(ticks)

# suppress the radial labels
plt.setp(ax.get_yticklabels(), visible=False)

#Bars to the wall
plt.ylim(0,2)

plt.legend(bbox_to_anchor=(1,0), fancybox=True, shadow=True)
plt.show()

Столбец 'Time' также можно преобразовать в радианы с помощью

def trans(x):
    h,m = map(int,x)
    return 2 * np.pi * (h + m/60)/24

xs = df['Time'].str.split(':')
xs = xs.apply(trans)

Что, вероятно, немного лучше, чем использование таймделты - это казалось немного запутанным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...