2017-01-27 12 views
1

저는 matplotlib (Python)에서 boxplot을 사용하여 상자 그림을 만들고, 다른 날짜로 많은 그래프를 작성하고 있습니다. x 축에서 데이터는 분리되어 있습니다.x 축 (matplotlib, boxplot)에 플롯 할 불연속 값을 어떻게 지정할 수 있습니까?

x 축의 값은 0.25, 0.5, 1, 2, 5 ... 28800입니다.이 값은 임의로 선택됩니다 (샘플링 기간 임). 일부 그래프에서는 데이터를 사용할 수 없어 하나 또는 두 개의 값이 누락되었습니다. 이 그래프에서 x 축은 다른 값을 펼치기 위해 자체 크기가 조정됩니다.

I는 (X 축에 값을 나타내고 있지만, 데이터는 그래프에 없음 존재하는 경우는 문제가되지 않는다)

모든 그래프는 x 축상의 동일한 위치에 동일한 값을 갖고 싶다

누군가 x 축 값을 지정하는 방법이 있는지 말해 줄 수 있습니까? 또는 같은 위치에 동일한 값을 유지하는 또 다른 방법입니다. myDataframe.groupby에서, ("날짜") 그룹 I에 대한


: 다음과 같이

코드의 관련 섹션은

graphFilename = (basename+'_' + str(i) + '.png') 
    plt.figure(graphFilename) 
    group.boxplot(by=["SamplePeriod_seconds"], sym='g+') ## colour = 'blue' 
    plt.grid(True) 
    axes = plt.gca() 
    axes.set_ylim([0,30000]) 
    plt.ylabel('Average distance (m)', fontsize =8) 
    plt.xlabel('GPS sample interval (s)', fontsize=8) 
    plt.tick_params(axis='x', which='major', labelsize=8) 
    plt.tick_params(axis='y', which='major', labelsize=8) 
    plt.xticks(rotation=90) 
    plt.title(str(i) + ' - ' + 'Average distance travelled by cattle over 24 hour period', fontsize=9) 
    plt.suptitle('') 
    plt.savefig(graphFilename) 
    plt.close()  

어떤 도움을, 그럴 게요 감사 인터넷 검색을 계속합니다. 감사합니다. :)

+0

.... p.s을 (나는 아마 :) 내가 지금 데이터를 볼 수 있습니다 작동 개선하지만 행복 할 수 실현). 축 일관성을 유지하고자하는 이유는 그래프를 훑어보고 쉽게 비교할 수 있기 때문입니다. – shara

답변

1

기본적으로 boxplot은 축의 연속적인 위치에 사용 가능한 데이터를 단순히 표시합니다. 누락 된 데이터는 boxplot이 누락되었음을 모르기 때문에 단순히 제외됩니다. 그러나 상자 위치는 positions 인수를 사용하여 수동으로 설정할 수 있습니다. 다음 예제는 이것을 수행하므로 값이없는 경우에도 같은 범위의 플롯을 생성합니다.

import matplotlib.pyplot as plt 
import numpy as np 
import pandas as pd 


basename = __file__+"_plot" 
Nd = 4 # four different dates 
Ns = 5 # five second intervals 
N = 80 # each 80 values 
date = [] 
seconds = [] 
avgdist = [] 
# fill lists 
for i in range(Nd): 
    # for each date, select a random SamplePeriod to be not part of the dataframe 
    w = np.random.randint(0,5) 
    for j in range(Ns): 
     if j!=w: 
      av = np.random.poisson(1.36+j/10., N)*4000+1000 
      avgdist.append(av) 
      seconds.append([j]*N) 
      date.append([i]*N) 

date = np.array(date).flatten() 
seconds = np.array(seconds).flatten() 
avgdist = np.array(avgdist).flatten() 
#put data into DataFrame 
myDataframe = pd.DataFrame({"Date" : date, "SamplePeriod_seconds" : seconds, "avgdist" : avgdist}) 
# obtain a list of all possible Sampleperiods 
globalunique = np.sort(myDataframe["SamplePeriod_seconds"].unique()) 

for i, group in myDataframe.groupby("Date"): 

    graphFilename = (basename+'_' + str(i) + '.png') 
    fig = plt.figure(graphFilename, figsize=(6,3)) 
    axes = fig.add_subplot(111) 
    plt.grid(True) 

    # omit the `dates` column 
    dfgroup = group[["SamplePeriod_seconds", "avgdist"]] 
    # obtain a list of Sampleperiods for this date 
    unique = np.sort(dfgroup["SamplePeriod_seconds"].unique()) 
    # plot the boxes to the axes, one for each sample periods in dfgroup 
    # set the boxes' positions to the values in unique 
    dfgroup.boxplot(by=["SamplePeriod_seconds"], sym='g+', positions=unique, ax=axes) 

    # set xticks to the unique positions, where boxes are 
    axes.set_xticks(unique) 
    # make sure all plots share the same extent. 
    axes.set_xlim([-0.5,globalunique[-1]+0.5]) 
    axes.set_ylim([0,30000]) 

    plt.ylabel('Average distance (m)', fontsize =8) 
    plt.xlabel('GPS sample interval (s)', fontsize=8) 
    plt.tick_params(axis='x', which='major', labelsize=8) 
    plt.tick_params(axis='y', which='major', labelsize=8) 
    plt.xticks(rotation=90) 
    plt.suptitle(str(i) + ' - ' + 'Average distance travelled by cattle over 24 hour period', fontsize=9) 
    plt.title("") 
    plt.savefig(graphFilename) 
    plt.close()  

이 여전히 작동합니다 enter image description here
enter image description here

, 경우 SamplePeriod_seconds columnare 비 동일한 간격, 그들은 매우 다른 경우지만 물론, 이것은 좋은 결과를 생산하지 않습니다 때문에의 값 바 overlapp됩니다

enter image description here

을이 그러나 자신을 음모를 꾸미고 문제가 아닙니다 . 추가 도움이 필요하면 그래프가 결국 어떻게 보이는지 알 필요가 있습니다.

+0

대단히 감사합니다 !! 이것에 대해 살펴보고 다시 해보겠습니다. 순간에 상자 플롯이 x 축에서 사용하는 값을 다시 읽는 방법을 배우고, 누락 된 값을 찾은 다음 해결하려고합니다. 그에 따라 간격을 다시 정렬하십시오. 도움을 감사하십시오. – shara

+0

위의 코드에서 'unique'을 사용했을 때와 같이 음모를 꾸미기 전에 누락 된 부분을 찾아내는 것이 좋습니다. 이렇게하면'positions' 인수를 사용하여 완전히 제어 할 수 있습니다. 감사합니다. – ImportanceOfBeingErnest

+0

! :) 나는 내일 또는 일요일 (거의 12am 내가 지금 어디에 있는지에 관해) 가도록시킬 것이다, 나는 내가 지금 어디인가에 도착하고있다라고 생각한다. 도와 주셔서 대단히 감사합니다! – shara

1

시도하면 다음과 같이 시도하십시오.

plt.xticks(np.arange(x.min(), x.max(), 5)) 

여기서 x는 x 값의 배열이고, 5는 축을 따라 취하는 단계입니다.

동일 내용은 y 축이있는 y 축에 적용됩니다. 희망이 도움이됩니다! :)

편집 :

내가하지 않은 인스턴스를 제거해야하지만, 다음 코드는 음모 당신에게 표를 주어야한다 위에 :

import matplotlib.pyplot as plt 
import numpy as np 


plt.grid(True) 
axes = plt.gca() 
axes.set_ylim([0, 30000]) 
plt.ylabel('Average distance (m)', fontsize=8) 
plt.xlabel('GPS sample interval (s)', fontsize=8) 
plt.tick_params(axis='x', which='major', labelsize=8) 
plt.tick_params(axis='y', which='major', labelsize=8) 
plt.xticks(rotation=90) 
plt.suptitle('') 
my_xticks =[0.25,0.5,1,2,5,10,20,30,60,120,300,600,1200,1800,2400,3‌000,3600,7200,10800,‌​ 14400,18000,21600,25‌​200,28800] 
x = np.array(np.arange(0, len(my_xticks), 1)) 

plt.xticks(x, my_ticks) 
plt.show() 

위에 당신의 가치에 연결해보십시오 of :

+0

대단히 고마워요! 나는 이것을 시도해 보았지만 아직 제대로 작동하지는 못했지만 몇 가지 시도를 해보면 잘 알려줄 것입니다. – shara

+0

흠, 내 x 축 값이 0이 아니기 때문에 작동하지 않는 것 같아요. 선형 스케일을 사용하지만 축에 균등하게 퍼트려고합니다. 그것들은 : (0.25,0.5,1,2,5,10203060120300600120018002400300036007200108001440018000216002520028800)입니다. 도와 주셔서 대단히 감사합니다! 나는 계속 노력할 것인데, 나는 x 축에서 그것들을 얻을 수 있었지만, 축상에 표시된 값에 대응하기보다는 순서대로 결과를 그렸다. 아마도 또한 값을 플로팅 할 때 사용하고있는 데이터 유형을 알아야 할 것입니다. 바라건대가 떠 다니지 만 문자열이나 다른 것일 수 있습니다. – shara

+0

축 전체에서 균등하게 무엇을 의미합니까? 수치 적으로는 의미가 없지만 위의 편집을 참조하십시오 :) – JB1

0

답장을 보내 주셔서 대단히 감사합니다. 다음 코드를 사용하여 답변을 얻었습니다.

valuesShouldPlot = ['0.25','0.5','1.0','2.0','5.0','10.0','20.0','30.0','60.0','120.0','300.0','600.0','1200.0','1800.0','2400.0','3000.0','3600.0','7200.0','10800.0','14400.0','18000.0','21600.0','25200.0','28800.0']  


for xDate, group in myDataframe.groupby("Date"):   ## for each date 

    graphFilename = (basename+'_' + str(xDate) + '.png') ## make up a suitable filename for the graph 

    plt.figure(graphFilename) 

    group.boxplot(by=["SamplePeriod_seconds"], sym='g+', return_type='both') ## create box plot, (boxplots are placed in default positions) 

    ## get information on where the boxplots were placed by looking at the values on the x-axis              
    axes = plt.gca() 
    checkXticks= axes.get_xticks() 
    numOfValuesPlotted =len(checkXticks)   ## check how many boxplots were actually plotted by counting the labels printed on the x-axis 
    lengthValuesShouldPlot = len(valuesShouldPlot) ## (check how many boxplots should have been created if no data was missing) 



    if (numOfValuesPlotted < valuesShouldPlot): ## if number of values actually plotted is less than the maximum possible it means some values are missing 
               ## if that occurs then want to move the plots across accordingly to leave gaps where the missing values should go 


     labels = [item.get_text() for item in axes.get_xticklabels()] 

     i=0     ## counter to increment through the entire list of x values that should exist if no data was missing. 
     j=0     ## counter to increment through the list of x labels that were originally plotted (some labels may be missing, want to check what's missing) 

     positionOfBoxesList =[] ## create a list which will eventually contain the positions on the x-axis where boxplots should be drawn 

     while (j < numOfValuesPlotted): ## look at each value in turn in the list of x-axis labels (on the graph plotted earlier) 

      if (labels[j] == valuesShouldPlot[i]): ## if the value on the x axis matches the value in the list of 'valuesShouldPlot' 
       positionOfBoxesList.append(i)  ## then record that position as a suitable position to put a boxplot 
       j = j+1 
       i = i+1 


      else :         ## if they don't match (there must be a value missing) skip the value and look at the next one    

       print("\n******** missing value ************") 
       print("Date:"), 
       print(xDate), 
       print(", Position:"), 
       print(i), 
       print(":"), 
       print(valuesShouldPlot[i]) 
       i=i+1    


     plt.close()  ## close the original plot (the one that didn't leave gaps for missing data) 
     group.boxplot(by=["SamplePeriod_seconds"], sym='g+', return_type='both', positions=positionOfBoxesList) ## replot with boxes in correct positions 

    ## format graph to make it look better   
    plt.ylabel('Average distance (m)', fontsize =8) 
    plt.xlabel('GPS sample interval (s)', fontsize=8) 
    plt.tick_params(axis='x', which='major', labelsize=8) 
    plt.tick_params(axis='y', which='major', labelsize=8) 
    plt.xticks(rotation=90) 
    plt.title(str(xDate) + ' - ' + 'Average distance travelled by cattle over 24 hour period', fontsize=9) ## put the title above the first subplot (ie. at the top of the page) 
    plt.suptitle('') 
    axes = plt.gca() 
    axes.set_ylim([0,30000]) 

    ## save and close 
    plt.savefig(graphFilename) 
    plt.close()