首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Matplotlib条形图-循环内建的图有时把条形图放置在错误的位置。

Matplotlib条形图-循环内建的图有时把条形图放置在错误的位置。
EN

Stack Overflow用户
提问于 2016-01-28 22:33:15
回答 1查看 657关注 0票数 0

我已经写了一个脚本,以建立一个“数字”地层剖面,显示地层变化随着时间的推移,一个模拟的地方景观。这个脚本是一个更大的项目的一部分,所以现在我正在随机生成海拔变化(每年间隔一次)。无论如何,我能够生成一个很好的数据,所有的地层数据都有正确的格式,我想用这些数据绘制一个图表,显示地层随时间的变化。时间应在X轴上,地层厚度应在Y上,不同地层应以颜色表示。我认为这样做的方法是在一个循环中建立一系列的条形图,并将它们从上到第一层覆盖。所以我把它编码起来,在模拟的每一个时间点,把地层的厚度绘制成一个条形图。从最年轻的阶层到最老的阶层,这实际上就是我要寻找的情节。问题是,每次跑步的最后一年左右的酒吧都被莫名其妙地放在了第五年,这似乎就像我每四、五次运行一次脚本。我似乎找不出发生这种事的原因,我已经检查了我能想到的一切。我显然需要另一双眼睛,我想知道是否有人能看到为什么会发生这种情况?我正在附上显示问题的输出数字。。代码在下面,标记了问题出现的位置。

代码语言:javascript
复制
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

############### SET UP INIT VALUES ##############
RunLength = 100 # Number of simulated "years"
initdepth = 1.5 # start with some depth (real script will read in from year 0 soildepth map)
prefix = "test2"
#################################################
#### Make some dummy erosion/deposition data ####
di = {k:np.random.normal(0.0075, 0.1, RunLength+1) for k in ["Delta"]} #random normal for elev change
di.update({y:np.arange(RunLength+1) for y in ["Year"]}) # set up column for years (0 to RunLength)
layers = pd.DataFrame(di) # make it into a dataframe
layers['Delta'][0] = 0 #set year 0 to have no change in all the columns
layers["Cumsum"] = layers.Delta.cumsum()+initdepth # calculate cumulative sum, and put it in a column in
layers.set_index('Year', inplace = True) # move the "Year" column to be the index
layers.T.to_csv("%s_CumED.csv" % prefix) # write out csv for posterity, and so we check out work
#####################################################################
### Assemble stratigraphic profile from erosion/deposition events ###
stratigraphy = pd.DataFrame({y:np.arange(RunLength+1) for y in ["Year"]}) #set up new dataframe to contain results of stratigraphic simulation
stratigraphy["Stratum0"] = initdepth # add a column for the base soil (stratum 0)
for idx, row in layers.iterrows(): # run a loop through the stratagraphic data to make "real" layers 
    if idx == 0: # Set up the pre-run soil-depth
        stratigraphy["Stratum0"][idx:RunLength+1] = initdepth # save current depth at this year for the stratum (and fill forward in time)
        old_delta = 0 # set up "old_delta" variable
        stratum = 0 # set up "stratum" variable
        currentdepth = initdepth
    else:
        currentdepth += row['Delta'] # figure out where the surface is this year
        if row['Delta'] >= 0: # Deposition happened this year...
            if old_delta >= 0: # ...and deposition happened last year too.
                stratigraphy["Stratum%s" % stratum][idx:RunLength+1] = currentdepth # continue building current stratum
            else: # ...but erosion happened last year.
                stratum += 1 # make new stratum
                stratigraphy["Stratum%s" % stratum] = 0.0 # add a column for the new stratum
                stratigraphy["Stratum%s" % stratum][idx:RunLength+1] = currentdepth # begin building new stratum
        else: # Erosion happened this year...
            for key in stratigraphy.keys(): #loop through strata
                if stratigraphy[key][idx] > currentdepth: # do we need to erode an old stratum?
                    stratigraphy[key][idx:RunLength+1] = currentdepth #erode!
        old_delta = row["Delta"]
##################################################################
### Make a plot showing how the stratigraphy changes over time ###
plt.ioff() # explicitly set interactive plotting off
sns.set_style("ticks") # set plot style with seaborn
sns.set_context("poster", font_scale = 1.1)
colors = sns.cubehelix_palette(stratum + 1, start=.75, rot=1.5, dark=.25) # grab nice cube helix color palette
fig, ax = plt.subplots(figsize=(17, 8)) #make blank plot with wide aspect ratio
ax.set_autoscale_on(False) # not sure if this doesn anything
### PROBLEM SEEMS TO BE HAPPENING IN HERE
for strat in reversed(range(stratum+1)): # loop through the strata, and overlay them on the plot
    ax.bar(stratigraphy.Year, stratigraphy.ix[:,strat+1], width=1, linewidth=0, color=colors[strat], label="Stratum %s" % strat) # this makes a new overlay for each strata across the years
### /PROBLEM    
ax.plot(layers.Delta.cumsum()+initdepth, color='black', drawstyle="steps-post") # plot a line of where the ground surface has been over time
ax.plot((0, np.amax(stratigraphy.Year)), (np.amax(stratigraphy.ix[:,stratum + 1]), np.amax(stratigraphy.ix[:,stratum + 1])), color='grey', linestyle='dashed') # plot a horizontal line for modern day surface
ax.set_xlim(0,np.amax(stratigraphy.Year)+2) # set limit of X axis a little larger to show last value
ax.set_ylim(0,np.amax(np.amax(stratigraphy.ix[:,1:stratigraphy.shape[1]]))) # set y axis range to match data range
ax.locator_params(nbins = 8) # set tick interval
plt.xlabel('Year')
plt.ylabel('Thickness of stratigraphic layers (m)')
ax.legend(loc='center left', bbox_to_anchor=(1.015, 0.5), fontsize='small', frameon='True', shadow='True', fancybox='True') # put legend of to right of the plot area
fig.subplots_adjust(left=0.065, right=0.90) #tighten up the layout
sns.despine(fig) # remove extraneous plot ticks
plt.savefig("%s_stratigraphy_stackedbar.png" % prefix, dpi=300) # save plot to file
plt.close()

编辑:添加最小的例子,下面。这是一个链接到一个示例CSV文件来使用它。

代码语言:javascript
复制
import pandas as pd
import matplotlib.pyplot as plt
stratigraphy = pd.read_csv('stratigraphy.csv')
plt.ioff() # explicitly set interactive plotting off
fig, ax = plt.subplots(figsize=(17, 8)) #make blank plot with wide aspect ratio
### PROBLEM SEEMS TO BE HAPPENING IN HERE
for strat in reversed(range(stratum+1)): # loop through the strata, and overlay them on the plot
    ax.bar(stratigraphy.Year, stratigraphy.ix[:,strat+1], width=1, linewidth=0, color=colors[strat], label="Stratum %s" % strat) # this makes a new overlay for each strata across the years
### /PROBLEM    
ax.set_xlim(0,np.amax(stratigraphy.Year)+2) # set limit of x axis
ax.set_ylim(0,np.amax(np.amax(stratigraphy.ix[:,1:stratigraphy.shape[1]]))) # set y axis range to match data range
plt.xlabel('Year')
plt.ylabel('Thickness of stratigraphic layers (m)')
plt.show()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-29 09:36:55

查看您的CSV文件,我可以看到没有年份(我假设是第一行) 200,而是值1.326197,这意味着最后一列数据将在开始的某个地方绘制。大小和位置匹配您的图表上的偏移栏。我不知道你为什么偶尔会看到它,但请确保你的数据生成正确。令我惊讶的是,你有201栏。因为Python从零开始计数,所以我假设这个数字将是100的乘法。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35073435

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档