2013-11-22 5 views
1

Я новичок в Python и MatPlotlib. Это мое первое сообщение для Stackoverflow - я не смог найти ответ в другом месте и был бы благодарен за вашу помощь.Пунктирный стиль линии из неравномерно распределенных данных

Я использую Windows XP с Enthought Canopy v1.1.1 (32 бит).

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

Точки в полученной пунктирной линии равномерно распределены вдоль линии регрессии и «размазаны вместе» в середине красной линии, что делает ее беспорядочной (см. Верхний график, полученный из прилагаемого минимального примера кода).

Это не происходит, если элементы массива значений x равномерно распределены (нижний график).

Я предполагаю, что это проблема с тем, как MatplotLib отображает пунктирные линии или как Canopy взаимодействует с Python с Matplotlib.

Пожалуйста, не могли бы вы рассказать мне обходное решение, которое сделает точки пунктирной линии равномерно распределенными; даже если данные x и y распределены неравномерно; в то время как все еще используют Canopy и Matplotlib?

(Как правило, я всегда стараюсь улучшить свои навыки кодирования - если какой-либо код в моем примере может быть написан более аккуратно или лаконично, я был бы благодарен за ваш опыт).

Большое спасибо в ожидании

Dave (Великобритания)

import matplotlib.pyplot as plt 
import numpy as np 
from scipy import stats 

#generate data 
x1=10 * np.random.random_sample((40)) 
x2=np.linspace(0,10,40) 
y=5 * np.random.random_sample((40)) 

slope, intercept, r_value, p_value, std_err = stats.linregress(x1,y) 
line = (slope*x1)+intercept 

plt.figure(1) 
plt.subplot(211) 
plt.scatter(x1,y,color='blue', marker='o') 
plt.plot(x1,line,'r:',label="Regression Line") 
plt.legend(loc='upper right') 

slope, intercept, r_value, p_value, std_err = stats.linregress(x2,y) 
line = (slope*x2)+intercept 

plt.subplot(212) 
plt.scatter(x2,y,color='blue', marker='o') 
plt.plot(x2,line,'r:',label="Regression Line") 
plt.legend(loc='upper right') 

plt.show() 

ответ

1

Добро пожаловать на SO.

Вы уже определили проблему самостоятельно, но, похоже, немного удивлены тем, что случайный x-массив приводит к тому, что строка будет «загромождена». Но вы нарисовываете пунктирную линию много раз над одним и тем же местом, поэтому мне кажется, что это нормальное поведение, что оно размывается в местах, где есть несколько пунктирных линий друг над другом.

Если вы этого не хотите, вы можете отсортировать свой массив и использовать его для расчета линии регрессии и построения графика. Поскольку его линейная регрессия, просто использование значений min и max также будет работать.

x1_sorted = np.sort(x1) 
line = (slope * x1_sorted) + intercept 

или

x1_extremes = np.array([x1.min(),x1.max()]) 
line = (slope * x1_extremes) + intercept 

Последнее должно быть быстрее, если x1 становится очень большим.

Что касается вашего последнего комментария. В вашем примере вы используете так называемую среду «state-machine» для построения графика. Это означает, что определенные команды применяются к активной фигуре и к активным осям (подзаголовкам).

Вы также можете рассмотреть подход OO, где вы получаете объекты с фигурами и осями. Это означает, что вы можете получить доступ к любой фигуре или осям в любое время, а не только к активному. Его полезно при передаче осей к функции, например.

В вашем примере оба будут работать одинаково хорошо, и это будет скорее вопросом вкуса.

Небольшой пример:

# create a figure with 2 subplots (2 rows, 1 column) 
fig, axs = plt.subplots(2,1) 

# plot in the first subplots 
axs[0].scatter(x1,y,color='blue', marker='o') 
axs[0].plot(x1,line,'r:',label="Regression Line") 

# plot in the second 
axs[1].plot() 
etc... 
Смежные вопросы