соединяя все точки заговора массива с помощью plt.plot () из matplotlib - PullRequest
3 голосов
/ 01 января 2012

У меня есть массив с координатами XY для точек. Я нанес на график каждую из этих точек и хочу линию, соединяющую каждую точку с каждой другой точкой (полный график). Массив представляет собой структуру 2x50, поэтому я переместил его и использовал представление, позволяющее перебирать строки. Тем не менее я получаю сообщение об ошибке «Индекс выходит за границы»:

     plt.plot(*zip(*v.T)) #to plot all the points
     viewVX = (v[0]).T
     viewVY = (v[1]).T
     for i in range(0, 49):
        xPoints = viewVX[i], viewVX[i+1]
        print("xPoints is", xPoints)
        yPoints = viewVY[i+2], viewVY[i+3]
        print("yPoints is", yPoints)
        xy = xPoints, yPoints
        plt.plot(*zip(*xy), ls ='-')

Я надеялся, что индексирование «обернется», так что для точек y оно начнется с y0, y1 и т. Д. Есть ли более простой способ достичь того, чего я пытаюсь достичь?

Ответы [ 4 ]

2 голосов
/ 02 января 2012
import matplotlib.pyplot as plt
import numpy as np
import itertools

v=np.random.random((2,50))
plt.plot(
    *zip(*itertools.chain.from_iterable(itertools.combinations(v.T,2))),
    marker='o', markerfacecolor='red')
plt.show()

Преимущество такого способа состоит в том, что звонков на plt.plot меньше. Это должно быть значительно быстрее, чем методы, которые делают O (N ** 2) вызовов plt.plot.

Обратите внимание, что вам не нужно наносить точки отдельно. Вместо этого вы можете использовать параметр marker='o'.


Пояснение: я думаю, что самый простой способ понять этот код - это посмотреть, как он работает с простым v:

In [4]: import numpy as np
In [5]: import itertools
In [7]: v=np.arange(8).reshape(2,4)
In [8]: v
Out[8]: 
array([[0, 1, 2, 3],
       [4, 5, 6, 7]])

itertools.combination (..., 2) создает все возможные пары точек:

In [10]: list(itertools.combinations(v.T,2))
Out[10]: 
[(array([0, 4]), array([1, 5])),
 (array([0, 4]), array([2, 6])),
 (array([0, 4]), array([3, 7])),
 (array([1, 5]), array([2, 6])),
 (array([1, 5]), array([3, 7])),
 (array([2, 6]), array([3, 7]))]

Теперь мы используем itertools.chain.from_iterable , чтобы преобразовать этот список пар точек в (уплощенный) список точек:

In [11]: list(itertools.chain.from_iterable(itertools.combinations(v.T,2)))
Out[11]: 
[array([0, 4]),
 array([1, 5]),
 array([0, 4]),
 array([2, 6]),
 array([0, 4]),
 array([3, 7]),
 array([1, 5]),
 array([2, 6]),
 array([1, 5]),
 array([3, 7]),
 array([2, 6]),
 array([3, 7])]

Если мы нанесем эти точки одну за другой, соединенные линиями, мы получим наш полный график. Единственная проблема состоит в том, что plt.plot(x,y) ожидает, что x будет последовательностью x -значений, а y будет последовательностью y -значений.

Мы можем использовать zip, чтобы преобразовать список точек в список значений x и y:

In [12]: zip(*itertools.chain.from_iterable(itertools.combinations(v.T,2)))
Out[12]: [(0, 1, 0, 2, 0, 3, 1, 2, 1, 3, 2, 3), (4, 5, 4, 6, 4, 7, 5, 6, 5, 7, 6, 7)]

Использование оператора splat (*) в zip и plt.plot - , объясненное здесь .

Таким образом, нам удалось втиснуть данные в правильную форму для подачи в plt.plot.

1 голос
/ 02 января 2012

Это то, что я придумал, но я надеюсь, что кто-то придумает что-нибудь получше.

def plot_complete(v):
     for x1, y1 in v.T:
          for x2, y2, in v.T:
             plt.plot([x1, x2], [y1, y2], 'b')
     plt.plot(v[0], v[1], 'sr')

. 'b' делает линии синими, а 'sr' отмечает точки красными квадратами.

1 голос
/ 01 января 2012

С массивом 2 на 50

 for i in range(0, 49):
    xPoints = viewVX[i], viewVX[i+1]
    print("xPoints is", xPoints)
    yPoints = viewVY[i+2], viewVY[i+3]

выйдет за пределы для i = 47 и i = 48, поскольку вы используете i+2 и i+3 в качестве индексов для viewVY.

0 голосов
/ 02 января 2012

Разобрались. В основном использовался упрощенный синтаксис, предоставляемый @Bago для построения графиков и учитывающий совет по индексированию @ Daniel. Просто нужно выполнить итерацию по каждому набору точек xy и создать новый набор точек xx 'yy', чтобы использовать их для отправки в plt.plot ():

        viewVX = (v[0]).T #this is if your matrix is 2x100 ie row [0] is x and row[1] is y
        viewVY = (v[1]).T
        for i in range(0, v.shape[1]): #v.shape[1] gives the number of columns
           for j in range(0, v.shape[1]):
              xPoints = viewVX[j], viewVX[i]
              yPoints = viewVY[j], viewVY[i]
              xy = [xPoints, yPoints]         #tuple/array of xx, yy point
              #print("xy points are", xy)
              plt.plot(xy[0],xy[1], ls ='-')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...