Python:动态地使用Matplotlib一次绘制许多行列表列表

时间:2017-05-02 15:35:36

标签: python list matplotlib dynamic collections

想要清理一些我目前非常混乱的代码。目标是在单个图上绘制多条线,但数据结构可能不同。

数据可以用几种不同的方式排列。

lats[set][point]
lons[set][point]

lat2[collection][set][point]
lon2[collection][set][point]

甚至只是xs和ys的常规列表,

我会在哪里插上相应的'到plt.plot(x,y),因为它是x或y的列表。我希望能够拥有尽可能多的列表,具体取决于我正在绘制的数据。目前我有一些基于类型排序的复杂检查,代码的基础如下。

def plotter(xs,ys):
    for x,y in zip(xs,ys):
        if type(x[0]) in (list, tuple):
            plotter(x,y)
        else:
            plt.plot(x,y)

开始变得复杂的是尝试将样式合并到不同深度的列表中。

我一直在尝试使用matplotlib.collections,但我还没有弄清楚如何正确使用它。任何帮助将不胜感激

1 个答案:

答案 0 :(得分:0)

一种解决方案是为包含实际数据的数据阵列生成所有可能的索引组合。下面是一些示例代码,可能看起来很复杂,但主要是生成和绘制数据。

有3个数据集(如您所建议的),其形式为:

  

lat1 - >积分

     

lat2 - >积分集合

     

lat3 - >点

以下是代码:

import matplotlib.pyplot as plt
import numpy as np
import itertools

# First data type
lat1 = np.array([np.linspace(0,180,100) for i in range(5)])
lon1 = np.array([10+5*np.random.random(100) for i in range(5)])
# lat1.shape = (5,100)
# [set][point]


# Second data type
lat2 = np.array([np.linspace(0,180,100) for i in range(5*3)]).reshape((3,5,100))
lon2 = np.array([30+10*np.random.random(100) for i in range(5*3)]).reshape((3,5,100))
# lat2.shape = (3,5,100)
# [collection][set][point]


# Third data type
lat3 = np.linspace(0,180,100)
lon3 = 50+5*np.random.random(100)
# lat3.shape = (100,)
# [point]


def plotter(xs,ys,ax,**kwargs):
    # Get number of dimensions
    ndim = xs.ndim

    # Iterate over each dimension, generating all indices
    if ndim>1:
        indices = [np.arange(0,i,1) for i in xs.shape[:-1]]
        comb = list(itertools.product(*indices))
    else:
        # This is to deal with one dimensional data (i.e. just a list)
        comb = [slice(0, xs.shape[0])]

    for c in comb:
        xx = xs[c]
        yy = ys[c]
        ax.plot(xx, yy, **kwargs)

    return ax

fig = plt.figure()
ax = fig.add_subplot(111)
plotter(lat1, lon1, ax, c='r', label='Type 1')
plotter(lat2, lon2, ax, c='b', label='Type 2')
plotter(lat3, lon3, ax, c='g', label='Type 3')

box = ax.get_position()
ax.set_position([box.x0, box.y0, box.width * 0.8, box.height])
ax.legend(fontsize=8,bbox_to_anchor=(1,1))

ax.set_ylim(0,60)
ax.set_xlim(0,180)

fig.show()

其中给出了下图:enter image description here