Matplotlib - линия тренда polyfit, кажется, перекрывает себя и выглядит нечеткой / неясной - PullRequest
1 голос
/ 03 мая 2019

Я пытаюсь построить некоторые линии тренда для некоторых данных, которые у меня есть.Проблема в том, что это выглядит нечетко и кажется перекрывающим себя, если я использую пунктирные или пунктирные стили.

Не знаю почему, но линии также выглядят так, как будто сглаживания не сделано - они выглядят неровными.Попытка создать точно такой же график в Excel дает чистые линии.

Использование других стилей линий не помогает;также не увеличивает интервал путем добавления тире = (1,5) или подобного.Даже если вы увеличите размер графика или измените ширину линии - он все равно перекрывается.

Вот код:

from matplotlib import pyplot as plt
import matplotlib.ticker as mtick
import numpy
from scipy import stats

radon = [49.6,61.7,58.7,64.1,59.4,64.6,65.4,65.3,65.5,66.0,50.5,64.8,71.9,
71.9,60.4,54.4,50.9,58.1,52.6,55.6,56.6,41.6,43.0,33.0,41.5,53.5,52.2,45.1,
46.8,63.0,73.8,61.3,44.4,39.3,38.2,45.4,39.9,36.3,41.0,38.5,35.4,40.2,11.3,
34.7,24.2,24.5,32.1,26.3,23.6,32.1,27.5,39.0,24.9,22.0,18.2,23.0,21.1,15.4,
13.9,10.2,26.4,18.2,16.6]

tout = [-2.57,-3.31,-0.63,-0.60,0.39,-1.64,-7.62,-1.90,-0.35,-4.88,-1.27,
-0.23,-6.99,-2.87,-12.27,-11.90,-9.42,-4.10,-3.15,0.81,3.87,-11.41,-9.47,
0.25,-6.81,-13.70,-16.41,-14.14,-9.70,-10.32,-21.83,-26.55,-16.88,-6.85,
4.03,-7.89,-6.53,-3.96,-6.09,-3.15,-0.51,-2.62,8.13,2.08,0.58,1.99,-6.64,
-12.13,-4.95,-2.99,-4.81,-0.88,0.28,-1.44,1.92,3.73,0.21,1.11,6.83,13.31,
7.04,1.46,1.78]

# start and end index for data
a = [0,21,42]
b = [20,41,62]

n = 0   # just a counter

# set font family
hfont = {'family':'Arial'}
plt.rcParams.update({'font.family': 'Arial', 'font.size':12})

# set axis minor tick marks
plt.axes().yaxis.set_minor_locator(mtick.MultipleLocator(4))
plt.axes().xaxis.set_minor_locator(mtick.MultipleLocator(2))
plt.axes().yaxis.set_major_formatter(mtick.FormatStrFormatter('%.0f%%'))

# config axis labels
plt.xlabel("Outdoor Temperature", **hfont)
plt.ylabel("Radiator on %", **hfont)

# set line and marker types and colors
marker = ['o', 's', 'x']
marker_facecolor = ['None', 'k', 'None']
names = ['Manual Control', 'Enforced Schedule', 'Occupancy-based']
lines = [':','--','-']
line_spacing = [[1, 5], [5, 5], [0, 0]]
transparency = [1, 0.75, 1]

for i,j in zip(a,b):
    # get x and y
    x = numpy.array(tout[i:j])
    y = numpy.array(radon[i:j])

    # set axis ranges
    plt.ylim(0, 100)
    plt.xlim(-30, 20)

    # plot data
    plt.plot(x, y, marker[n],markeredgewidth=0.75
    ,markeredgecolor='k',markerfacecolor=marker_facecolor[n],
    alpha=transparency[n],label=names[n])

    # perform regressions
    z = numpy.polyfit(x, y, 1)
    p = numpy.poly1d(z)

    # plot trendline
    plt.plot(x,p(x),'k%s' % lines[n], linewidth=0.85)

    # increment counter
    n+=1

plt.legend(loc='upper right')
leg = plt.legend()
leg.get_frame().set_edgecolor('k')

plt.savefig('tout_vs_radon.png', dpi=300)
plt.show()

Вот результат кода выше: https://i.imgur.com/K6jIHBM.png (нерепутация не достаточна для публикации изображения, извините)

Вы можете видеть линию тренда, перекрывающую себя в центре для пунктирных или пунктирных стилей.Я использую matplotlib v3.0.3 и Python v3.6.5 для Windows 10.

1 Ответ

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

Ключ должен был бы построить массив в сортированном виде . В противном случае линия будет прыгать вперед и назад и перекрывать себя.

order = np.argsort(x)
plt.plot(x[order],p(x[order]), ..)

Полный код:

from matplotlib import pyplot as plt
import matplotlib.ticker as mtick
import numpy as np

radon = [49.6,61.7,58.7,64.1,59.4,64.6,65.4,65.3,65.5,66.0,50.5,64.8,71.9,
71.9,60.4,54.4,50.9,58.1,52.6,55.6,56.6,41.6,43.0,33.0,41.5,53.5,52.2,45.1,
46.8,63.0,73.8,61.3,44.4,39.3,38.2,45.4,39.9,36.3,41.0,38.5,35.4,40.2,11.3,
34.7,24.2,24.5,32.1,26.3,23.6,32.1,27.5,39.0,24.9,22.0,18.2,23.0,21.1,15.4,
13.9,10.2,26.4,18.2,16.6]

tout = [-2.57,-3.31,-0.63,-0.60,0.39,-1.64,-7.62,-1.90,-0.35,-4.88,-1.27,
-0.23,-6.99,-2.87,-12.27,-11.90,-9.42,-4.10,-3.15,0.81,3.87,-11.41,-9.47,
0.25,-6.81,-13.70,-16.41,-14.14,-9.70,-10.32,-21.83,-26.55,-16.88,-6.85,
4.03,-7.89,-6.53,-3.96,-6.09,-3.15,-0.51,-2.62,8.13,2.08,0.58,1.99,-6.64,
-12.13,-4.95,-2.99,-4.81,-0.88,0.28,-1.44,1.92,3.73,0.21,1.11,6.83,13.31,
7.04,1.46,1.78]

# start and end index for data
a = [0,21,42]
b = [20,41,62]

n = 0   # just a counter

# set font family
hfont = {'family':'Arial'}
plt.rcParams.update({'font.family': 'Arial', 'font.size':12})

# set axis minor tick marks
plt.gca().yaxis.set_minor_locator(mtick.MultipleLocator(4))
plt.gca().xaxis.set_minor_locator(mtick.MultipleLocator(2))
plt.gca().yaxis.set_major_formatter(mtick.FormatStrFormatter('%.0f%%'))

# config axis labels
plt.xlabel("Outdoor Temperature", **hfont)
plt.ylabel("Radiator on %", **hfont)

# set line and marker types and colors
marker = ['o', 's', 'x']
marker_facecolor = ['None', 'k', 'None']
names = ['Manual Control', 'Enforced Schedule', 'Occupancy-based']
lines = [':','--','-']
line_spacing = [[1, 5], [5, 5], [0, 0]]
transparency = [1, 0.75, 1]

for i,j in zip(a,b):
    # get x and y
    x = np.array(tout[i:j])
    y = np.array(radon[i:j])

    # set axis ranges
    plt.ylim(0, 100)
    plt.xlim(-30, 20)

    # plot data
    plt.plot(x, y, marker[n],markeredgewidth=0.75,
             markeredgecolor='k',markerfacecolor=marker_facecolor[n],
             alpha=transparency[n],label=names[n])

    # perform regressions
    z = np.polyfit(x, y, 1)
    p = np.poly1d(z)

    # plot trendline
    order = np.argsort(x)
    plt.plot(x[order],p(x[order]),'k%s' % lines[n], linewidth=0.85)

    # increment counter
    n+=1

plt.show()

enter image description here

...