Python 从定义的x/y范围的数据框中打印pcolormesh,即使该行或列没有';不存在于已筛选的数据帧中

Python 从定义的x/y范围的数据框中打印pcolormesh,即使该行或列没有';不存在于已筛选的数据帧中,python,pandas,matplotlib,Python,Pandas,Matplotlib,我已将一些数据加载到具有多条记录的pandas数据框中。每个记录都有一个小时值和一个工作日值。我正在将它们旋转到一个二维矩阵中,用pyplot.pcolormesh进行绘图。问题是当我过滤表时,我得到的2D矩阵在我的输出中没有任何整列/整行的值。如何强制pcolormesh遵守xrange/yrange并用零或nodata值填充这些单元格 def timeHeatmap(data): for group in data.GroupID.unique(): data_day

我已将一些数据加载到具有多条记录的pandas数据框中。每个记录都有一个小时值和一个工作日值。我正在将它们旋转到一个二维矩阵中,用pyplot.pcolormesh进行绘图。问题是当我过滤表时,我得到的2D矩阵在我的输出中没有任何整列/整行的值。如何强制pcolormesh遵守xrange/yrange并用零或nodata值填充这些单元格

def timeHeatmap(data):
    for group in data.GroupID.unique():
        data_daytime = pd.pivot_table(data[data['GroupID'] == group], index='Weekday', columns='Hour', values='Value', aggfunc=np.count_nonzero)
        data_daytime = data_daytime.fillna(0)

        # Plot it out
        fig, ax = plt.subplots()
        ax.set_aspect('equal')
        plt.axis([0, 24, 0, 7])
        heatmap = ax.pcolormesh(data_daytime, cmap=plt.cm.Reds, alpha=1)
        plt.colorbar(mappable=heatmap, orientation='horizontal', label='Number of Crashes')

        # Format
        fig = plt.gcf()
        fig.set_size_inches(11, 8)

        # turn off the frame
        ax.set_frame_on(False)

        # put the major ticks at the middle of each cell
        ax.set_yticks(np.arange(data_daytime.shape[0]) + 0.5, minor=False)
        ax.set_xticks(np.arange(data_daytime.shape[1]) + 0.5, minor=False)

        # want a more natural, table-like display
        ax.invert_yaxis()
        ax.xaxis.tick_top()

        # Set the labels
        xlabels = ['12a','1a','2a','3a','4a','5a','6a','7a','8a','9a','10a','11a','12p','1p','2p','3p','4p','5p','6p','7p','8p','9p','10p','11p']
        ylabels = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']

        # note I could have used nba_sort.columns but made "labels" instead
        ax.set_xticklabels(xlabels, minor=False)
        ax.set_yticklabels(ylabels, minor=False)

        # rotate the
        #plt.xticks(rotation=90)

        ax.grid(False)

        # Turn off all the ticks
        ax = plt.gca()

        for t in ax.xaxis.get_major_ticks():
            t.tick1On = False
            t.tick2On = False
        for t in ax.yaxis.get_major_ticks():
            t.tick1On = False
            t.tick2On = False

        plt.savefig('Group{}.png'.format(group), dpi=300, facecolor=None, edgecolor=None, format='png', transparent=True, bbox_inches='tight')
我找到的唯一限制/min/max/范围是颜色渐变(clim)和Z值(vmin/vmax)

编辑:尝试使用ax.set\u xlim(),但无效:
ax.set_xlim()
ax.set_ylim()
允许您在matplotlib中调整轴边界。

问题 很难告诉plotting函数绘制一些根本不存在的数据。matplotlib如何知道缺少值

让我们考虑这个例子

import pandas as pd
import numpy as np; np.random.seed(6)
import matplotlib.pyplot as plt

n=31
hours = np.random.randint(1,13,size=n)
days = np.random.choice(['Mon','Tue','Wed','Fri','Sat','Sun'], size=n)
value = np.random.poisson(size=n)
df = pd.DataFrame({'Weekday' : days, 'Hour':hours, 'Value':value})
print (df)

piv = pd.pivot_table(df, index='Weekday', columns='Hour', values='Value')
piv = piv.fillna(0)
print(piv)
这将生成以下透视表,其中缺少星期四和8点

Hour      1    2    3    4         5    6    7    9    10   11   12
Weekday                                                            
Fri      0.0  0.0  1.0  0.0  0.666667  0.0  0.0  0.0  1.0  0.0  0.0
Mon      0.0  2.0  0.0  0.0  0.000000  1.0  0.0  0.0  0.0  1.0  0.0
Sat      1.0  0.0  0.0  0.0  0.000000  1.0  0.0  0.0  0.0  0.0  0.0
Sun      0.0  0.0  0.0  0.0  1.000000  0.0  0.0  0.0  0.0  1.0  2.5
Tue      0.0  0.0  0.0  0.0  0.000000  1.0  1.0  0.0  0.0  0.0  0.0
Wed      0.0  0.5  1.0  1.0  0.000000  0.0  0.0  2.0  1.5  1.5  0.0
策划这个,

fig, ax = plt.subplots()
ax.set_aspect('equal')
plt.axis([0, 12, 0, 7])
heatmap = ax.pcolormesh(piv, cmap=plt.cm.Reds, alpha=1)

ax.set_yticks(np.arange(piv.shape[0]) + 0.5, minor=False)
ax.set_xticks(np.arange(piv.shape[1]) + 0.5, minor=False)
ax.set_xticklabels(piv.columns, minor=False)
ax.set_yticklabels(piv.index, minor=False)
plt.show()
生成没有缺失值的绘图,这是不需要的,但可以清楚地理解,因为它们不在数据帧中,因此绘图函数不知道

解决办法 一个解决方案是创建另一个数据框,其中包含
NaN
s,实际上包含了所有索引和列,我们稍后要用数据创建的透视表绘制和更新此数据框

alldays = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
allhours = np.arange(1,13)
# Full dataframe with NaNs
full = pd.DataFrame(columns=allhours, index=alldays)
# pivot from data
piv = pd.pivot_table(df, index='Weekday', columns='Hour', values='Value')
# fill full dataframe with pivot values
full.update(piv)
piv = full
piv = piv.fillna(0)
print(piv)
给出以下透视表,该透视表在8o点钟列和星期四行中有零

      1    2    3    4         5    6    7   8    9    10   11   12
Mon  0.0  2.0  0.0  0.0  0.000000  1.0  0.0   0  0.0  0.0  1.0  0.0
Tue  0.0  0.0  0.0  0.0  0.000000  1.0  1.0   0  0.0  0.0  0.0  0.0
Wed  0.0  0.5  1.0  1.0  0.000000  0.0  0.0   0  2.0  1.5  1.5  0.0
Thu  0.0  0.0  0.0  0.0  0.000000  0.0  0.0   0  0.0  0.0  0.0  0.0
Fri  0.0  0.0  1.0  0.0  0.666667  0.0  0.0   0  0.0  1.0  0.0  0.0
Sat  1.0  0.0  0.0  0.0  0.000000  1.0  0.0   0  0.0  0.0  0.0  0.0
Sun  0.0  0.0  0.0  0.0  1.000000  0.0  0.0   0  0.0  0.0  1.0  2.5
打印此操作将生成所需的打印

完整代码:

import pandas as pd
import numpy as np; np.random.seed(6)
import matplotlib.pyplot as plt

n=31
hours = np.random.randint(1,13,size=n)
days = np.random.choice(['Mon','Tue','Wed','Fri','Sat','Sun'], size=n)
value = np.random.poisson(size=n)
df = pd.DataFrame({'Weekday' : days, 'Hour':hours, 'Value':value})
print (df)

alldays = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun']
allhours = np.arange(1,13)
full = pd.DataFrame(columns=allhours, index=alldays)
piv = pd.pivot_table(df, index='Weekday', columns='Hour', values='Value')
full.update(piv)
piv = full
piv = piv.fillna(0)
print(piv)

fig, ax = plt.subplots()
ax.set_aspect('equal')
plt.axis([0, 12, 0, 7])
heatmap = ax.pcolormesh(piv, cmap=plt.cm.Reds, alpha=1)

ax.set_yticks(np.arange(piv.shape[0]) + 0.5, minor=False)
ax.set_xticks(np.arange(piv.shape[1]) + 0.5, minor=False)
ax.set_xticklabels(piv.columns, minor=False)
ax.set_yticklabels(piv.index, minor=False)
plt.show()

使用ax.set\u xlim(0,24)尝试了它,但除了翻转y轴之外,它没有工作。。。哎呀。。。请看我的图片编辑。这个答案不是很有建设性。仅仅在轴上设置一些限制将无助于显示不存在的数据。这只会造成很多空白。@ScottBoston,如果你不告诉我你认为我做错了什么,那就没什么帮助了。。。