简体   繁体   English

Python:使用Matplotlib动态绘制多个行列表的列表

[英]Python: Plot many lists of lists of lines at once with Matplotlib dynamically

Looking to clean up some code I have that's currently very messy. 寻找清理一些代码,我目前非常混乱。 The goal is to plot many lines on a single plot, but the data can be structured differently. 目标是在一个图上绘制多条线,但是数据的结构可以不同。

The data can be arranged in a few different ways.. 数据可以几种不同的方式排列。

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

or 要么

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

or even just a regular list of xs, and ys, 甚至只是xs和ys的常规列表,

Where I would plug the respective 'set' into plt.plot(x,y) as it is a list of xs or ys. 我将把相应的“集合”插入plt.plot(x,y)的地方,因为它是xs或ys的列表。 I want to be able to have the as many lists deep as I need, depending on the data that I'm plotting. 我希望能够根据需要绘制尽可能多的列表,这取决于我要绘制的数据。 Currently I have a few complex checks that sort based on the type, the base of the code is below. 目前,我有一些根据类型进行排序的复杂检查,下面是代码的基础。

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)

What starts getting complex is trying to incorporate styles for different depths of lists. 变得越来越复杂的是尝试为不同深度的列表合并样式。

I've been trying to use the matplotlib.collections but I haven't quite figured out how to use it correctly. 我一直在尝试使用matplotlib.collections,但我还没有弄清楚如何正确使用它。 Any help would be appreciated 任何帮助,将不胜感激

One solution is to generate all possible combinations of indices for the data arrays that contain the actual data. 一种解决方案是为包含实际数据的数据阵列生成所有可能的索引组合。 Below is some example code, which might seem convoluted but is mostly generating and plotting the data. 以下是一些示例代码,这些代码看起来似乎有些费解,但主要用于生成和绘制数据。

There are 3 data sets (as you suggested), that have the forms: 有3个数据集(如您建议的那样),其格式如下:

lat1 -> set of points lat1->点集

lat2 -> collection of sets of points lat2->点集的集合

lat3 -> points lat3->点

Here is the code: 这是代码:

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()

Which gives the following figure: 如下图所示: 在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM