Построение фреймов данных, содержащих формат ЧЧ: ММ, в однозначном матплотлибе - PullRequest
1 голос
/ 22 мая 2019

Мой вопрос (написанный в конце ниже) связан с построением гистограмм двух DataFrames на разных подцифрах ( Ситуация 1 ниже ) по сравнению с отображением их на одном и том же рисунке ( Ситуация 2 ниже ). Гистограммы строятся с интервалом в 1 час в качестве критерия группировки. Оба кадра данных имеют один столбец с временами в формате "HH:MM".

# Defining the two DataFrames
df_in = pd.DataFrame({'time': ['12:20', '12:06', '11:30', '11:03', '10:44', '10:50', '11:52', 
                               '12:21', '9:58', '12:43','12:56', '13:27', '12:14',]})

df_out = pd.DataFrame({'time': ['19:40', '19:44', '19:21', '20:37', '20:27', '18:46', '19:42', 
                                '18:12', '19:08', '21:09', '18:37', '20:34', '20:15']})

Ситуация 1 : построение обоих фреймов данных в разных подцифрах

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.ticker import FixedFormatter

fig, axes = plt.subplots(1, 2, figsize=(9, 3))

colors = ['r', 'b']
titles = ['df-in', 'df-out']

# Looping over the dataframes and plotting them in subfigures
for df, ax, c, t in zip([df_in, df_out], axes.flatten(), colors, titles):
    df['hour'] = pd.to_datetime(df['time'], format='%H:%M')
    df.set_index('hour', drop=False, inplace=True)
    df = df['hour'].groupby(pd.Grouper(freq='60Min')).count()
    df.plot(kind='bar', color=c, ax=ax)
    ticklabels = df.index.strftime('%H:%Mh')
    ax.xaxis.set_major_formatter(FixedFormatter(ticklabels))
    ax.set_title(t, fontsize=18)
plt.show()

Выход ситуации 1

enter image description here


Ситуация 2 : отображение обоих фреймов данных на одном и том же рисунке

fig, axes = plt.subplots(figsize=(7, 3))

# Looping over the dataframes and plotting them in subfigures
for df, c, t in zip([df_in, df_out], colors, titles):
    df['hour'] = pd.to_datetime(df['time'], format='%H:%M')
    df.set_index('hour', drop=False, inplace=True)
    df = df['hour'].groupby(pd.Grouper(freq='60Min')).count()
    df.plot(kind='bar', color=c, ax=axes)
    ticklabels = df.index.strftime('%H:%Mh')
    axes.xaxis.set_major_formatter(FixedFormatter(ticklabels))
plt.show() 

Выход ситуации 2

enter image description here

В обоих случаях код для форматирования строк взят из этого вопроса. Как вы можете видеть, красная и синяя гистограммы имеют соответствующие максимумы в 12:00 и 19:00 ч, если они представлены отдельно. Но когда я строю их на одном графике, две гистограммы перекрываются, а максимумы не в 12:00 и 19:00 ч. Проблема кажется тривиальной, но я не уверен, что происходит не так.


Мой вопрос : что необходимо изменить в Ситуация 2 , чтобы обе гистограммы были хорошо разделены и различимы (вместо перекрытия), поскольку они четко центрированы около 12:00 а 19:00 ч? Любые указатели и предложения приветствуются.

Ответы [ 2 ]

2 голосов
/ 22 мая 2019

Вы также можете использовать мощный оттенок sns:

# convert to time
df_in.time = pd.to_datetime(df_in.time)
df_out.time = pd.to_datetime(df_out.time)

# mark the series/dataframe and join
df_in['df'] = 'df_in'
df_out['df'] = 'df_out'
df = pd.concat((df_in,df_out))

# groupby hours:
df = df.groupby(['df',df.time.dt.hour]).size().reset_index()

# plot with sns
plt.figure(figsize=(10,6))
sns.barplot(x='time', 
            y=0,
            hue='df', 
            dodge=False,
            data=df)
plt.show()

Выход:

enter image description here


Изменить: чтобы построить столбцы с осью х от 7 до 23, мы можем reindex перед графиком:

df = (df.groupby(['df', df.time.dt.hour]).size()
        .reset_index(level=0).reindex(range(7,24))
        .reset_index()
     )

И барплот sns дает:

enter image description here

1 голос
/ 22 мая 2019

Числовая гистограмма может выглядеть так:

import pandas as pd
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
import matplotlib.pyplot as plt
from matplotlib.dates import HourLocator, DateFormatter


# Defining the two DataFrames
df_in = pd.DataFrame({'time': ['12:20', '12:06', '11:30', '11:03', '10:44', '10:50', '11:52', 
                               '12:21', '9:58', '12:43','12:56', '13:27', '12:14',]})

df_out = pd.DataFrame({'time': ['19:40', '19:44', '19:21', '20:37', '20:27', '18:46', '19:42', 
                                '18:12', '19:08', '21:09', '18:37', '20:34', '20:15']})

colors = ['r', 'b']
titles = ['df-in', 'df-out']

fig, ax = plt.subplots(figsize=(7, 3))


for df, c, t in zip([df_in, df_out], colors, titles):
    df['hour'] = pd.to_datetime(df['time'], format='%H:%M')
    df.set_index('hour', drop=False, inplace=True)
    df = df['hour'].groupby(pd.Grouper(freq='60Min')).count()
    df.index = pd.to_datetime(df.index)
    ax.bar(df.index, df.values, width=1/24/2, color=c, label=t)

ax.xaxis.set_major_locator(HourLocator())
ax.xaxis.set_major_formatter(DateFormatter("%H:%Mh"))
ax.set_xlim(pd.to_datetime(["1900-01-01 07:00", "1900-01-01 23:00"]))
plt.setp(ax.get_xticklabels(), rotation=90)
plt.tight_layout()
plt.show() 

enter image description here

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