【问题标题】:How to plot a calendar using matplotlib patches如何使用 matplotlib 补丁绘制日历
【发布时间】:2020-05-22 17:40:36
【问题描述】:

我想创建一个演示日历,它反映特定事件发生的风险一个月中的每一天,以及每个单独的设备

我在网上看到了这篇文章:

# Demo plot 
import calendar
import numpy as np
from matplotlib.patches import Rectangle
import matplotlib.pyplot as plt
def plot_calendar(days, months):
    plt.figure(figsize=(9, 3))
    # non days are grayed
    ax = plt.gca().axes
    ax.add_patch(Rectangle((29, 2), width=.8, height=.8, 
                           color='gray', alpha=.3))
    ax.add_patch(Rectangle((30, 2), width=.8, height=.8,
                           color='gray', alpha=.5))
    ax.add_patch(Rectangle((31, 2), width=.8, height=.8,
                           color='gray', alpha=.5))
    ax.add_patch(Rectangle((31, 4), width=.8, height=.8,
                           color='gray', alpha=.5))
    ax.add_patch(Rectangle((31, 6), width=.8, height=.8,
                           color='gray', alpha=.5))
    ax.add_patch(Rectangle((31, 9), width=.8, height=.8,
                           color='gray', alpha=.5))
    ax.add_patch(Rectangle((31, 11), width=.8, height=.8,
                           color='gray', alpha=.5))
    for d, m in zip(days, months):
        ax.add_patch(Rectangle((d, m), 
                               width=.8, height=.8, color='C0'))
    plt.yticks(np.arange(1, 13)+.5, list(calendar.month_abbr)[1:])
    plt.xticks(np.arange(1,32)+.5, np.arange(1,32))
    plt.xlim(1, 32)
    plt.ylim(1, 13)
    plt.gca().invert_yaxis()
    # remove borders and ticks
    for spine in plt.gca().spines.values():
        spine.set_visible(False)
    plt.tick_params(top=False, bottom=False, left=False, right=False)
    plt.show()


from datetime import datetime, timedelta
def get_weekends(year):
    weekend_day = []
    weekend_month = [] 
    start = datetime(year, 1, 1)
    for i in range(365):
        day_of_the_year = start + timedelta(days=i)
        if day_of_the_year.weekday() > 4:
            weekend_day.append(day_of_the_year.day)
            weekend_month.append(day_of_the_year.month)
    return weekend_day, weekend_month
weekend_day, weekend_month = get_weekends(2018)
plot_calendar(weekend_day, weekend_month)

并返回下面的日历:

首先,我想创建一个类似的图表,但不是在Y-axis 上设置月份,而是将device_1 设置为device_100,(即日历将适用于超过 100 个设备月)

其次,我想在网格中使用不同(或仅 2 种)颜色来表示不同的风险级别。

无论如何,主要目的是创建一个演示日历以可视化潜在风险,我不确定如何。

【问题讨论】:

    标签: python pandas numpy matplotlib graph


    【解决方案1】:

    这可以通过对您的代码进行以下修改来实现。新函数接受一个参数days,它应该是一个(day, color) 元组列表,用于标记您要绘制的每个设备。它还需要一个可选参数 days_in_month 来构建与少于 31 天的月份的兼容性。

    代码:

    def plot_device_calendar(days, days_in_month=31):
        plt.figure(figsize=(.3*days_in_month, .3*len(days)))
        ax = plt.gca().axes
        for device, days_to_mark in enumerate(days, start=1):
            for d in days_to_mark:
                ax.add_patch(Rectangle((d[0], device), 
                                       width=.8, height=.8, color=d[1]))
        plt.yticks(np.arange(1, len(days)+1)+.5, [f"device_{i}" for i in range(1, len(days)+1)])
        plt.xticks(np.arange(1,days_in_month+1)+.5, np.arange(1,days_in_month+1))
        plt.xlim(1, days_in_month+1)
        plt.ylim(1, len(days)+1)
        plt.gca().invert_yaxis()
        for spine in plt.gca().spines.values():
            spine.set_visible(False)
        plt.tick_params(top=False, bottom=False, left=False, right=False)
        plt.show()
    

    示例输入:(3 台设备,10 个随机日期和颜色)

    >>> l = [[(30, 'r'), (23, 'b'), (31, 'g'), (16, 'm'), (10, 'g'), (7, 'r'), (27, 'g'), (6, 'y'), (3, 'y'), (14, 'g')],
             [(22, 'y'), (21, 'w'), (16, 'y'), (23, 'c'), (8, 'g'), (31, 'w'), (15, 'k'), (12, 'k'), (6, 'm'), (24, 'r')],
             [(31, 'c'), (10, 'c'), (2, 'k'), (17, 'g'), (30, 'y'), (3, 'g'), (14, 'y'), (23, 'y'), (4, 'r'), (22, 'r')]]
    

    用法:

    >>> colors = ['b','g','r','c','m','y','k','w']
    >>> l = [random.sample(range(1,32), 10) for i in range(20)]
    >>> l = [[(x,random.choice(colors)) for x in sl] for sl in l]
    >>> plot_device_calendar(l)
    

    输出:

    【讨论】:

    • 漂亮的代码和情节。我想知道是否所有颜色都可以遵循相同的配色方案,只是为了显示相关性?谢谢
    • @nilsinelabore 你可以传递任何你想要的颜色——matplotlib 颜色:如 ['r'、'b'、'g'、'c']、matplotlib 配色方案:如 [' C0', 'C1', ...] 甚至 RGBA 元组:[(1,0,0,1), (0,1,0,1), (0,0,1,1), ... ] 请参阅matplotlib.org/2.0.2/api/colors_api.html 了解更多详情。
    猜你喜欢
    • 2014-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多