Как сделать график плотности из множества отдельных функций? - PullRequest
0 голосов
/ 29 сентября 2018

Скажем, функция просто

def linear(x,n):
    return n+x

И что совокупность параметров, которые нужно попробовать, равна

import numpy as np
parameters = np.random.normal(0, 1, 1000)

Какой лучший способ построить всю совокупность функций?

Прямым является

import matplotlib.pyplot as plt
for n in parameters: plt.plot(x,linear(x,n))

Однако, когда параметров много (например, 1e5), это невозможно.Я думаю, что правильный способ сделать это может быть в соответствии с графиком 2D-плотности или 2D-гистограммой, но я не уверен, как применить их к моей проблеме.

Еще одно осложнение: каждая из моделей попробовалавыше имеет свое собственное значение оценки соответствия, например, $ \ chi ^ 2 $.После получения графика, показывающего плотность моделей в виде цветового кода, я хотел бы раскрасить его цветом по значению $ \ chi ^ 2 $.Опять же, я прошу идеи или опыт.

Любое предложение очень приветствуется!

1 Ответ

0 голосов
/ 30 сентября 2018

Для вашего примера вы можете связать данные в соответствии с параметрами n и соответствующим образом закрепить вывод функции.Я приведу быстрый пример ниже.Если зависимость функции от n является более сложной, то схема (повторного) биннинга также может стать более сложной.Но это зависит от конкретного случая.В случае, если распределение значений параметров n неравномерно (как в вашем примере), можно рассматривать фиксированные ячейки ширины, а не скользящее среднее.Но опять же, это дело вкуса.

from timeit import timeit
import matplotlib
from matplotlib.colors import Normalize
import matplotlib.pyplot as plt
import numpy as np

def linear(x,n):
    return n+x

N = 1000
x = np.linspace(0, 1, N)
n = np.random.normal(0, 1, N)

cmap = matplotlib.cm.get_cmap('plasma')
norm = Normalize(vmin=n.min(), vmax=n.max())

def p3():
    n2, x2 = np.meshgrid(n, x)
    f = linear(x2, n2)
    # Now comes the "histogram" step. It involves taking the average over neighboring samples.
    # Since data can be distributed non-linearly this might not be the desired behavior but
    # similarly it is possible to specify an array of bins and use this for the binning.
    sort = np.argsort(n)
    n2 = n2[:, sort]
    f = f[:, sort]
    rebin = 10
    n2 = n2.reshape(n2.shape[0], -1, rebin).mean(axis=-1)  # Average over 10 samples.
    f = f.reshape(f.shape[0], -1, rebin).mean(axis=-1)
    x2 = x2[:, ::rebin]  # No average required here, values are the same along second axis.
    plt.figure()
    plt.title('Using histogram method and pcolor')
    plt.pcolor(x2, f, n2, cmap=cmap, norm=Normalize(vmin=n2.min(), vmax=n2.max()))

p3()
plt.show()

Histogram pcolor

Я также проверил отдельные линейные графики и график рассеяния.Точечная диаграмма уменьшает количество вызовов API, однако, хотя фактический вызов имеет схожую синхронизацию, я обнаружил, что обновление холста занимает значительно больше времени (в фоновом потоке; аналогично для сохранения в png, например).

def p1():
    plt.figure()
    plt.title('Plotting individual functions')
    for nn in n:
        plt.plot(x, linear(x, nn), '-', color=cmap(norm(nn)))

def p2():
    n2, x2 = np.meshgrid(n, x)
    f = linear(x2, n2)
    plt.figure()
    plt.title('Using scatter')
    plt.scatter(x2.ravel(), f.ravel(), color=cmap(norm(n2.ravel())))

print('p1: ', timeit('p1()', setup='from __main__ import p1', number=1))
print('p2: ', timeit('p2()', setup='from __main__ import p2', number=1))
plt.show()

Lines

Scatter

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