2017-01-12 3 views
3

Я хочу построить в CDF данных на логнормальном вероятности график, как показано ниже:Python Логнормального Вероятность Plot

enter image description here

Я хочу топоры чешуйка на моем участке, чтобы выглядеть, только перевернутые (с вероятностью на оси х). Обратите внимание, что вышеописанная ось Y не просто логарифмическая шкала. Также я не уверен, почему ось x выше повторяет 1-9 вместо перехода на 10-99 и т. Д., Но игнорирует эту часть.

Вот что у меня есть. Я использую метод, чтобы сделать CDF, как описано here

mu, sigma = 3., 1. # mean and standard deviation 
data = np.random.lognormal(mu, sigma, 1000) 

#Make CDF 
dataSorted = np.sort(data) 
dataCdf = np.linspace(0,1,len(dataSorted)) 

plt.plot(dataCdf, dataSorted) 
plt.gca().set_yscale('log') 
plt.xlabel('probability') 
plt.ylabel('value') 

enter image description here

Теперь мне просто нужен способ, чтобы масштабировать свою ось х как ось у на картинке выше.

+1

Это то, что вам нужно: [Plot логарифмических осей с Matplotlib в питоне] (http://stackoverflow.com/questions/773814/plot-logarithmic-axes-with-matplotlib-in -python)? – Lucas

+1

Разве не очевидно, как вы можете сделать логарифмическую ось x из вашего текущего кода? 'plt.gca(). set_yscale ('log')' -> 'plt.gca(). set_xscale ('log')' –

+0

Шкала x (или y-масштаб в осях примера) не является логарифмической. Я изменил образ осей примера для ясности. «Средние» значения вероятности близки друг к другу, большие/малые друг от друга. Его похоже на его логарифмическое значение до 0,5 и «обратно» логарифмическое от 0,5 до 1 – hm8

ответ

2

Способом решения этой проблемы является использование симметричной шкалы журнала, называемой symlog.

Symlog - логарифмический график, который ведет себя линейно в пределах некоторого диапазона вокруг 0 ​​(где нормальный график логарифма будет отображаться бесконечно много десятилетий), так что возможен логарифмический график, пересекающий 0.

Symlog может быть установлен в matplotlib с использованием ax.set_xscale('symlog', linthreshx=0.1), где linthreshx обозначает линейный диапазон вокруг нуля.

Как и в этом случае, мы хотим, чтобы центр графика был равен 0,5 вместо 0, мы можем на самом деле построить два графика и соединить их вместе. Чтобы получить желаемый результат, теперь можно играть с отмеченными отметками, а также с параметром linthreshx. Ниже приведен пример.

import matplotlib.pyplot as plt 
import numpy as np 
import matplotlib.ticker 
mu, sigma = 3., 1. # mean and standard deviation 
data = np.random.lognormal(mu, sigma, 1000) 

#Make CDF 
dataSorted = np.sort(data) 
dataCdf = np.linspace(0,1,len(dataSorted)) 

fig, (ax1, ax2) = plt.subplots(ncols=2, sharey=True) 
plt.subplots_adjust(wspace=0.00005) 
ax1.plot(dataCdf[:len(dataCdf)/2], dataSorted[:len(dataCdf)/2]) 
ax2.plot(dataCdf[len(dataCdf)/2:]-1, dataSorted[len(dataCdf)/2:]) 

ax1.set_yscale('log') 
ax2.set_yscale('log') 

ax1.set_xscale('symlog', linthreshx=0.001) 
ax2.set_xscale('symlog', linthreshx=0.001) 

ax1.set_xlim([0.01, 0.5]) 
ax2.set_xlim([-0.5, -0.01]) 

ticks = np.array([0.01,0.1, 0.3]) 
ticks2 = ((1-ticks)[::-1])-1 
ax1.set_xticks(ticks) 
ax1.xaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter()) 
ax2.set_xticks(ticks2) 
ax2.xaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter()) 
ax2.set_xticklabels(ticks2+1) 

ax1.spines["right"].set_visible(False) 
ax2.spines["left"].set_visible(False) 
ax1.yaxis.set_ticks_position('left') 
ax2.yaxis.set_ticks_position('right') 

ax1.set_xlabel('probability') 
ax1.set_ylabel('value') 

plt.savefig(__file__+".png") 
plt.show() 

enter image description here

+0

Как оказалось, на самом деле это не то, что я ищу. Логарифмическое распределение должно отображаться как абсолютно прямая линия на графике. Моя интерпретация «логарифмическая до 0,5 и« обратно »логарифмическая от 0,5 до 1 должна быть неверной. – hm8