Много сюжетов за меньшее время - питон - PullRequest
0 голосов
/ 02 февраля 2019

У меня около 50 000 столбцов, которые я хочу нарисовать на одном рисунке.Вот код, который я использую:

# "Xaxis" is a list containing the x-axis, and "data" a list of the 50 000 data series I want to plot.
for elt in data:
    plt.plot(Xaxis,elt)

Это занимает немного времени (мне нужно подождать около 15 минут).Любые предложения по оптимизации процесса / сокращению времени?

Спасибо!

1 Ответ

0 голосов
/ 06 февраля 2019

Ответ в одном предложении: используйте LineCollection.


Существует несколько вариантов рисования множества линий.

A.Цикл

Можно зациклить данные и создать один plot на строку.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection


def loop(N, show=False):
    x = np.random.rand(N,3)
    y = np.random.rand(N,3)

    fig, ax = plt.subplots()
    for i in range(N):
        ax.plot(x[i], y[i])

    if show:
        plt.show()
    else:
        fig.canvas.draw()
    plt.close(fig)

B.Построить матрицу

Вместо нескольких вызовов plot, можно указать матрицу для plot, где каждый столбец содержит значения строки.Однако при этом все равно будет создано столько Line2D объектов, сколько столбцов в матрице.

def matrix(N, show=False):
    x = np.random.rand(N,3)
    y = np.random.rand(N,3)

    fig, ax = plt.subplots()

    ax.plot(x.T, y.T)

    if show:
        plt.show()
    else:
        fig.canvas.draw()
    plt.close(fig)

C.A LineCollection

Коллекция позволяет создать одного художника, который отображается только один раз.Это самый быстрый вариант.

from matplotlib.collections import LineCollection

def linecoll(N, show=False):
    x = np.random.rand(N,3)
    y = np.random.rand(N,3)

    data = np.stack((x,y), axis=2)
    fig, ax = plt.subplots()

    ax.add_collection(LineCollection(data))

    if show:
        plt.show()
    else:
        fig.canvas.draw()
    plt.close(fig)

D.Одиночный график с nans.

Линия будет перехвачена в позициях значений nan в данных.Это позволяет построить одну Line2D, но с nan s в конце каждого блока данных, который составляет отдельную строку.

def fillednan(N, show=False):
    x = np.random.rand(N,3)
    y = np.random.rand(N,3)

    X = np.concatenate((x, np.ones_like(x)*np.nan)).flatten()
    Y = np.concatenate((y, np.ones_like(x)*np.nan)).flatten()

    fig, ax = plt.subplots()

    ax.plot(X,Y)

    if show:
        plt.show()
    else:
        fig.canvas.draw()
    plt.close(fig)

Результаты.

Запуск этих функций для различных значений от N до %timeit приводит к следующему графику.

enter image description here

Мы видим, что LineCollection занимает наименьшее количество времени.Для больших N различия значительны.Цикл наименее эффективен, за ним следует матрица.Это потому, что оба создают N отдельных линий, которые нужно нарисовать.Одна строка с nans и LineCollection намного эффективнее, а LineCollection по-прежнему опережает plot.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...