Вопрос о форматировании DataFrame для использования с matplotlib - PullRequest
1 голос
/ 13 мая 2019

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

Рабочий раствор:

plt.plot(arange(0, 16*pi, Dt), u[:, index])
plt.show()

Это здорово и супер просто! Приведенный ниже метод также был найден в документации по matplotlib, но он дает неверный график. Я хотел бы знать мою ошибку:

нерабочий раствор:

df = pd.DataFrame({'t':arange(0, 16*pi, Dt), 'u':u[:,index]})
plt.plot('t', 'u', data=df)
plt.show()

полный код для контекста

from math import sin, cos, pi, fabs, log10, ceil, floor
from numpy import arange, zeros
import pandas as pd
from matplotlib import pyplot as plt


#function applies periodic boundary condition where h is the period
def apply_pbc(f, i, Dx, M, h):
    f[i][0] = f[i][int(h/Dx)]
    f[i][int((M + Dx)/Dx)] = f[i][int((M + Dx)/Dx - 1)]

    return f

# function for finding an index associated with
# a particular data point of interest for plotting
# or other analysis
def find_index(start, stop, step, x):
    counter = len(arange(start, stop, step))
    for i in arange(counter):
        x_i = start + i*step
        if abs(x - x_i) < pow(10, -15):
            index = i
            print("x = ", x_i, "@index j = ", i)
            break

    return index

#main body
if __name__ == "__main__":

    #constants
    a = 0.25
    b = 0.25
    c = 1

    #period of boundary conditions
    h = 4*pi

    #space and time endpoints
    M = 4*pi
    N = 16*pi

    #mesh
    Dx = 0.005*4*pi
    Dt = (0.25*Dx)/c

    #simplification of numeric method
    r = (Dt*pow(c,2))/pow(Dx,2)

    #get size of data set
    rows = len(arange(0, N, Dt))
    cols = len(arange(-Dx, M, Dx))

    #initiate solution arrays
    u = zeros((rows, cols))
    v = zeros((rows, cols))

    #apply initial conditions
    for j in range(cols):
        x = -Dx + j*Dx
        u[0][j] = cos(x)
        v[0][j] = 0


    #solve
    for i in range(1, rows):
        for j in range(1, cols - 1):
            u[i][j] = u[i-1][j] + v[i-1][j]*Dt \
                    + (a/2)*(u[i-1][j+1] - 2*u[i-1][j] + u[i-1][j-1])

            v[i][j] = v[i-1][j] \
                    + r*(u[i-1][j+1] - 2*u[i-1][j] + u[i-1][j-1]) \
                    + (b/2)*(v[i-1][j+1] - 2*v[i-1][j] + v[i-1][j-1])
        apply_pbc(u, i, Dx, M, h)
        apply_pbc(v, i, Dx, M, h)

    print("done")

    #we want to plot the solution u(t,x), where x = pi
    index = find_index(-Dx, M + Dx, Dx, pi)

    df = pd.DataFrame({'t':arange(0,16*pi, Dt), 'u':u[:,index]})
    plt.plot('t', 'x', data=df)
    # plt.plot(arange(0, 16*pi, Dt), u[:, index])
    plt.show()

1 Ответ

0 голосов
/ 13 мая 2019

Из документации plt.plot () :

Построение данных с метками

Существует удобный способ построения объектов с помеченными данными (т.е. даннымик нему можно получить доступ по индексу obj ['y']).Вместо того, чтобы давать данные в x и y, вы можете предоставить объект в параметре data и просто дать метки для x и y:

plot('xlabel', 'ylabel', data=obj)

Я думаю, что в вашем коде есть просто опечатка.В полном коде, который вы предоставляете, это линия, которая составляет график:

plt.plot('t', 'x', data=df)

, который действительно дает

enter image description here

при изменении на

plt.plot('t', 'u', data=df)

работает как положено: enter image description here

Последний бит кода:

df = pd.DataFrame({'t':arange(0,16*pi, Dt), 'u':u[:,index]})
plt.plot('t', 'x', data=df)  # <-- 'x' instead of 'u'
# plt.plot(arange(0, 16*pi, Dt), u[:, index])
plt.show()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...