matplotlib 创建一个关于击球次数演变的图表

h43kikqp  于 2023-01-26  发布在  其他
关注(0)|答案(1)|浏览(101)

我得到了一个数据框,像这样:

Team     Time     
8   Red 00:02:31   
10 Blue 00:03:01  
12  Red 00:85:31  
14 Blue 00:87:02  
 ...

PS:它代表了比赛的镜头。
我想做一个这样的图表:

第一,我的df是否可以这样做,或者我必须改变它?第二,我怎么做?

vc9ivgsu

vc9ivgsu1#

这可能是解决这个问题的一种方法,这里我使用了Seaborn object interface,从v0.12开始提供。

import pandas as pd
import seaborn as sns
import seaborn.objects as so
import matplotlib as mpl
from matplotlib.dates import MinuteLocator

sns.set_theme()

df_original = pd.DataFrame(
    {
        'Team': ['red', 'red', 'red', 'blue', 'blue', 'blue', 'blue', 'red', 'red', 'blue', 'red', 'blue'],
        'Time': ['1900-01-01 00:09:01', '1900-01-01 00:15:03', '1900-01-01 00:18:04', '1900-01-01 00:33:11', '1900-01-01 00:36:12', '1900-01-01 00:57:23', '1900-01-01 01:06:25', '1900-01-01 01:09:26', '1900-01-01 01:15:28', '1900-01-01 01:21:31', '1900-01-01 01:24:33', '1900-01-01 01:27:35']
    },
    index=[4, 8, 10, 20, 22, 36, 42, 44, 48, 52, 54, 56]
)

df = (df_original
    .assign(Team=df.Team.astype("category"),
            Time=pd.to_datetime(df.Time))
)

(
    so.Plot(df, x="Time", color="Team")

    # Workaround for passing datetime for `bins`
    # c.f. https://github.com/mwaskom/seaborn/issues/2371#issuecomment-768637786
    .add(so.Bar(), so.Hist(bins=mpl.dates.date2num(pd.date_range("1900-01-01", end="1900-01-01 02", freq="5min"))), so.Dodge())

    .scale(
        color=so.Nominal(values=["red", "blue"], order=["red", "blue"]),
        x=so.Temporal().tick(locator=MinuteLocator(interval=5)).label(concise=True),
        y=so.Continuous().tick(every=1)
    )

    # To adjust x-tick to start from `00:00`, shifting start time 10 sec. Hacky :(
    .limit(x=(mpl.dates.date2num(pd.to_datetime("1900-01-01") - pd.to_timedelta(10, unit="S")), None))

    .layout(size=(10, 3))
)

相关问题