【问题标题】:Is there a good way to visualize large number of subplots (> 500)?有没有一种可视化大量子图(> 500)的好方法?
【发布时间】:2016-12-26 15:18:46
【问题描述】:

我仍在处理我的纽约地铁数据。我以这样一种方式清理和整理数据,现在我在周末和工作日将每个站点每小时的“平均入口”和“平均出口”(范围从 0 到 23)分开(类别变量具有两个可能的值:周末/工作日)。

我试图做的是创建一个图,每个站都是一行,每行有两列(第一列是工作日,第二列是周末)。我想每小时绘制“平均入口”和“平均出口”,以获取有关车站的一些信息。这里有两件有趣的事情;首先,纯粹的数字表明车站有多忙;其次,给定小时内的出入口之间的比率,以表明车站是生活区(早上的入口负载,晚上的出口负载)还是更多的工作区域(早上的出口负载,入口负载在下午 4 点、6 点和 8 点左右偷看)。唯一的问题,大约有 550 个站点。

我尝试使用 seaborn facetgrid 绘制它,它无法处理多个站点(10 个左右)而不会遇到内存问题。

所以我想知道是否有人有一个好主意来完成我想做的事情。

请找到随附的笔记本(倒数第二个单元格显示了我对数据进行可视化的尝试,即 4 个站点的绘图)。这显然不适用于 500 多个站点,所以可能是连续 5 个站点?

最后一个单元格包含评论中要求的 Station R001 的数据..

https://github.com/FBosler/Udacity/blob/master/Example.ipynb

非常感谢任何输入! 费边

【问题讨论】:

标签: python pandas matplotlib visualization subplot


【解决方案1】:

除非你有一整面监视器墙,否则无论你做什么,在屏幕上显示它们都会遇到问题,但是为了绕过内存限制,你可以将它们光栅化并保存到图像文件(我会建议使用 .png 来压缩具有几种不同颜色的图像)

你想要的是pyplot.savefig()

Here's 另一个问题的答案,其中包含一些提示和技巧

【讨论】:

  • 如果我只是想感受一下数据,这绝对是我会做的。将每个图形的绘图保存到文件中,然后像浏览照片库一样浏览它们。如果您想要一个令人印象深刻的可视化演示,请获取地铁系统的 SVG 地图,并编写一些 javascript 以在用户单击或悬停在车站上时显示每个车站的图。做起来没那么难。
  • 顺便说一句,如果您从笔记本制作这些绘图,请确保禁用 %matplotlib inline 否则您将在创建所有绘图时遇到内存问题(这是一个已知的笔记本问题:github.com/ipython/ipython/issues/7270 )。
  • @VictorChubukov 感谢您的反馈!你的想法显然是一个非常熟练的程序员会采取的路线:) 它可能远远高于我的水平,但假设我想做你建议的事情,我将如何去做/我必须先学习什么?
  • @FabianBosler 如果你朝那个方向走,有很多选择。我的建议是从D3.js 的一些基本教程开始,并使用 svg。但其他人可能有完全不同的方法。
【解决方案2】:

与其制作 550 多个子图,不如看看是否可以制作两个大的 numpy 数组,然后使用 2 个 imview 子图,一个用于工作日,一个用于周末

对于 y 值,首先找到平均值的最小值 (0) 和最大值 (10,000?),将它们缩放以适合每个假行,例如 10px,然后将数据中的每一行偏移 10px *行号。

由于您需要为 24 个数据点中的每一个数据点绘制线图,因此您必须在数据点之间以 10 像素的增量进行线性插值,以便最终的 numpy 数组为 240 x 5500 x 2 .

【讨论】:

    【解决方案3】:

    一种可能的方法是使用每个站点的入口与出口的比率。每天/每小时可以在图像上形成一列,每一行都是一个站。例如:

    from matplotlib import pyplot as plt
    import random
    import numpy as np
    
    
    all_stations = []
    
    for i in range(550):
        entries = [float(random.randint(0, 50)) for i in range(7*24)] # Data point for each hour over a week
        exits = [float(random.randint(0, 50)) for i in range(7*24)]
    
        weekend_entries = entries[:2*7]
        weekend_exits = exits[:2*7]
    
        day_entries = entries[2*7:]
        day_exits = exits[2*7:]
    
        weekend_ratio = [np.array(en) / np.array(ex) for en, ex in zip(weekend_entries, weekend_exits)]
        day_ratio = [np.array(en) / np.array(ex) for en, ex in zip(day_entries, day_exits)]
    
        whole_week = weekend_ratio + day_ratio
    
        all_stations.append(whole_week)
    
    plt.figure()
    plt.imshow(all_stations, aspect='auto', interpolation="nearest")
    plt.xlabel("Hours")
    plt.ylabel("Station number")
    plt.title("Entry/exit ratio per station")
    plt.colorbar(label="Entry/exit ratio")
    # Add some vertical lines to indicate days
    for j in range(1, 7):
        plt.plot([j*24]*2, [0, 550], color="black")
    plt.xlim(0, 7*24)
    plt.ylim(0, 550)
    plt.show()
    

    如果您想显示所涉及的实际数字而不是比率,我会考虑将数据分成两部分,每个条目和出口数据集一张图像。然后可以使用每个像素的强度来告知数字,而不是比率。

    【讨论】:

    • 我真的很喜欢您将数据显示为一站一排的想法。不过我会做一些调整。 1. 小时是分类的(范围从 0 到 23) 2. 我认为用一个迷你条形图来代替颜色会很酷。 3. 将 24 小时类别细分为每个进入和退出,以便每个小时列有两个子列,其中有一个红色(分别为绿色)条表示平均退出(进入) 4. 周末的第二个图表。这有意义吗?
    • 是的,您可能可以将所有这些都放入像数组这样的图像中,但是当您想要不同的颜色代表不同的事物时,它会变得更加复杂。对于第 1 点,您可以重新标记 x 轴以反映您的命名类别,请参阅 plt.xlabels(['cata', 'catb', 'catc' etc])。对于第 2 点,您可以添加另一行或进一步拆分列,我可能会添加另一行,因此每个站点都有一个红色行和一个绿色行,这样更容易比较。要让它工作会有点麻烦,您需要构建自己的 rgb-a 图像,每个像素都自定义
    猜你喜欢
    • 2016-09-09
    • 2013-01-09
    • 2010-09-17
    • 2021-09-30
    • 1970-01-01
    • 2014-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多