本文介绍了如何使用Python创建历史时间表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我在这里看到了一些答案,对您有所帮助,但是我的数据集比之前回答的要大.为了大致了解我正在使用的工具,请

然后,为了复制您的夏王朝制片,我刚刚创建了一个子集:

在此之后,我主要保持了您/Evgeny的代码已经显示的内容,并做了一些小改动:

  event = data_set_xia ['EnglishName']开始= data_set_xia ['开始']结束= data_set_xia ['完成']长度= data_set_xia ['长度'] 

我在此处添加了一个用于用垂直线命名的级别(您可以加长或缩短数组[-2、2,-1、1]以获得不同级别的标签):

  levels = np.tile([-2,2,-1,1],int(np.ceil(len(begin)/4)))[:len(begin)]导入matplotlib.pyplot作为pltplt.style.use('ggplot')plt.figure(figsize =(12,6)) 

在这里,我基本上将所有朝代都添加到相同的 y 标量(列为0)上,其余的行已进行了修改,以对应于条形图的颜色并提供边缘色.

  plt.barh(0,(end-begin),color = data_set_xia.loc [:,"Dynasty_col"],height = 0.3,left = begin,edgecolor ="black")plt.tick_params(axis ='both',which ='major',labelsize = 15)plt.tick_params(axis ='both',which ='minor',labelsize = 20)plt.title('夏朝',fontsize ='25')plt.xlabel('Year',fontsize ='20')#plt.yticks(range(len(begin)),")斧= plt.gca()ax.axes.yaxis.set_visible(False)plt.xlim(-2250,-1700)ylim(-5,5) 

我在标签的垂直线上玩了些,标签与关卡相关联以创建情节.

  plt.vlines(开头+长度/2、0,级别,颜色="tab:red")对于我在范围(18)中:plt.text(begin.iloc [i] + length.iloc [i]/2,等级[i] * 1.3,event.iloc [i],ha ='center',fontsize ='12')plt.tight_layout()plt.show() 

这产生了以下有关夏朝的图表:

使用更大的子集,我也可以生成另一个图:和

现在,显然,条目数越多,图表变得更加繁忙和混乱,并且看上去有点难看,但仍然清晰可见.另外,代码也不是完美的",我会对其进行一些清理,并在barh的参数中更改一些命令选项,例如 color ,但现在可以使用.

对于另一种表示方式,由于某些朝代相互重叠,我按时间添加了不同朝代的交错表示代码:

  event = data_set_adj ['EnglishName']开始= data_set_adj ['开始']结束= data_set_adj ['完成']长度= data_set_adj ['长度']王朝= data_set_adj ['Dynasty']dynasty_col = data_set_adj ['Dynasty_col']dict_dynasty = dict(zip(dynasty.unique(),range(0,4 * len(dynasty.unique()),4)))等级= np.tile([-1.2,1.2,-0.8,0.8,-0.4,0.4],int(np.ceil(len(begin)/6)))[:len(begin)]导入matplotlib.pyplot作为pltplt.style.use('ggplot')plt.figure(figsize =(20,10))对于x范围(len(朝代)):plt.vlines(begin.iloc [x] + length.iloc [x]/2,dict_dynasty [dynasty.iloc [x]],dict_dynasty [dynasty.iloc [x]] +等级[x],color ="tab":red)plt.barh(dict_dynasty [dynasty.iloc [x]],(end.iloc [x] -begin.iloc [x]),color = dynasty_col.iloc [x],高度= 0.3,left = begin.iloc [x],edgecolor ="black",alpha = 0.5)如果x%2 == 0:plt.text(begin.iloc [x] + length.iloc [x]/2,dict_dynasty [dynasty.iloc [x]] + 1.6 * levels [x],event.iloc [x],ha ='center',fontsize ='8')别的:plt.text(begin.iloc [x] + length.iloc [x]/2,dict_dynasty [dynasty.iloc [x]] + 1.25 * levels [x],event.iloc [x],ha ='center',fontsize ='8')plt.tick_params(axis ='both',which ='major',labelsize = 15)plt.tick_params(axis ='both',which ='minor',labelsize = 20)plt.title('中国王朝',fontsize ='25')plt.xlabel('Year',fontsize ='20')斧= plt.gca()ax.axes.yaxis.set_visible(False)xlim(900,1915)ylim(-4,28)plt.tight_layout()plt.show() 

最后一部分是仓促完成的,因此代码并不是最整洁的,但是我在这里所做的唯一更改是根据数据子集中的朝代更新了barh的 y 标量.我正在考虑.我已经修改了级别和字体大小以提高可读性,您可以使用数字和代码来获得适当的表示形式.

这将导致以下表示:

此外,当我添加Age_col列时,您可以将整个内容归类为帝国前"和帝国"(红色或蓝色).我暂时没有附加任何图形,但是如果您添加带有不同"zorder"颜色的该色块,则可以使用该图形王朝左右.

对于可缩放和可缩放的图形,我想使用bokeh或其他类似的库进行绘制会更好,那样,您可以使其整洁并集中于有意义的部分?

So I've seen a few answers on here that helped a bit, but my dataset is larger than the ones that have been answered previously. To give a sense of what I'm working with, here's a link to the full dataset. I've included a picture of one attempted solution, which was found at this link:.

The issue is that 1. This is difficult to read and 2. I don't know how to flatten it out so that it looks like a traditional timeline. The issue becomes more apparent when I try and work with larger segments, such as this one, which is basically unreadable:Here's the code I used to produce both of these (I just modified the included code in order to change which section of the overall dataset was used).

event = Xia['EnglishName']
begin = Xia['Start']
end = Xia['Finish']
length = Xia['Length']

plt.figure(figsize=(12,6))
plt.barh(range(len(begin)), (end-begin), .3, left=begin)
plt.tick_params(axis='both', which='major', labelsize=15)
plt.tick_params(axis='both', which='minor', labelsize=20)
plt.title('Xia Dynasty', fontsize = '25')
plt.xlabel('Year', fontsize = '20')
plt.yticks(range(len(begin)), "")
plt.xlim(-2250, -1750)
plt.ylim(-1,18)
for i in range(18):
    plt.text(begin.iloc[i] + length.iloc[i]/2, i+.25, event.iloc[i], ha='center', fontsize = '12')

This code semi-works, but I'd prefer if the bars were either closer together or differently colored and all on the same y-value. I appreciate any and all help. I've been trying to figure this out for about two weeks now and am hitting a brick wall.

解决方案

I don't know whether you already resolved this problem or not, but, from what I have seen so far from your code and (also borrowing from Evgeny's code) your requirements, the only reason you have the different levels of horizontal bars because you have defined the scalar y of the barh of matplotlib (matplotlib.pyplot.barh(y, width, height=0.8, left=None, *, align='center', **kwargs) as a range. So, each successive stacked bar is being listed on a separate level.

So, I took the liberty of downloading your dataset and playing around with the code a little bit.

I created a dataframe from the google dataset and assigned each of the Dynasty (Dynasty_col column) and Age (Age_col column) with a matplotlib CSS color (this is not necessary, but, I find this easier to manage for visualisation):

Then for the purpose of replicating your Xia Dynasty representation, I just created a subset:

Following that I kept mostly to what your/Evgeny's code already shows with a few minor changes:

event = data_set_xia['EnglishName']
begin = data_set_xia['Start']
end = data_set_xia['Finish']
length =  data_set_xia['Length']

Here I added a level for naming with a vertical line (you can lengthen or shorten the array [-2, 2, -1, 1] to get different levels of labelling):

levels = np.tile([-2, 2, -1, 1],
                 int(np.ceil(len(begin)/4)))[:len(begin)]

import matplotlib.pyplot as plt
plt.style.use('ggplot')
plt.figure(figsize=(12,6))

Here I basically add all of the dynasties on the same y scalar (listed as 0), the rest of the line has been modified to correspond to the color of the bars and give an edgecolour.

plt.barh(0, (end-begin), color=data_set_xia.loc[:,"Dynasty_col"], height =0.3 ,left=begin, edgecolor = "black")
plt.tick_params(axis='both', which='major', labelsize=15)
plt.tick_params(axis='both', which='minor', labelsize=20)
plt.title('Xia Dynasty', fontsize = '25')
plt.xlabel('Year', fontsize = '20')
# plt.yticks(range(len(begin)), "")
ax = plt.gca()
ax.axes.yaxis.set_visible(False)
plt.xlim(-2250, -1700)
plt.ylim(-5,5)

I played around a bit with vertical lines for labels and the labels were associated with the levels to create the plot.

plt.vlines(begin+length/2, 0, levels, color="tab:red")
for i in range(18):
    plt.text(begin.iloc[i] + length.iloc[i]/2,
             levels[i]*1.3, event.iloc[i],
             ha='center', fontsize = '12')

plt.tight_layout()
plt.show()

This resulted in the following graphs for the Xia dynasty:

And using a bigger subset, I could generate this other graph too:and

Now obviously, the longer the number of entries are, the busier and the more cluttered the graphs become and it starts looking a bit ugly, but it is still legible. Also, the code is not "perfect", I would clean it up a bit and change some command options like the color in the arguments in barh, but it works for now.

For an alternate representation, I am adding the code of staggered representation of the different dynasties by time, as some of the dynasties overlap with each other:

event = data_set_adj['EnglishName']
begin = data_set_adj['Start']
end = data_set_adj['Finish']
length =  data_set_adj['Length']
dynasty = data_set_adj['Dynasty']
dynasty_col = data_set_adj['Dynasty_col']

dict_dynasty = dict(zip(dynasty.unique(), range(0,4*len(dynasty.unique()),4)))

levels = np.tile([-1.2,1.2, -0.8, 0.8, -0.4, 0.4],
                 int(np.ceil(len(begin)/6)))[:len(begin)]

import matplotlib.pyplot as plt
plt.style.use('ggplot')
plt.figure(figsize=(20,10))

for x in range(len(dynasty)):
    plt.vlines(begin.iloc[x]+length.iloc[x]/2, dict_dynasty[dynasty.iloc[x]], dict_dynasty[dynasty.iloc[x]]+levels[x], color="tab:red")
    plt.barh(dict_dynasty[dynasty.iloc[x]], (end.iloc[x]-begin.iloc[x]), color=dynasty_col.iloc[x], height =0.3 ,left=begin.iloc[x], edgecolor = "black", alpha = 0.5)
    if x%2==0:
        plt.text(begin.iloc[x] + length.iloc[x]/2,
                 dict_dynasty[dynasty.iloc[x]]+1.6*levels[x], event.iloc[x],
                 ha='center', fontsize = '8')
    else:
        plt.text(begin.iloc[x] + length.iloc[x]/2,
                 dict_dynasty[dynasty.iloc[x]]+1.25*levels[x], event.iloc[x],
                 ha='center', fontsize = '8')
plt.tick_params(axis='both', which='major', labelsize=15)
plt.tick_params(axis='both', which='minor', labelsize=20)
plt.title('Chinese Dynasties', fontsize = '25')
plt.xlabel('Year', fontsize = '20')
ax = plt.gca()
ax.axes.yaxis.set_visible(False)
plt.xlim(900, 1915)
plt.ylim(-4,28)


plt.tight_layout()
plt.show()

This last part was done hastily, so the code is not the neatest, but the only thing I changed here was update the y scalar of barh based on the dynasties in the data sub-set that I am considering. I have modified the levels and the fontsize for readability, you can play around with the numbers and the code to get the appropriate representations.

This results in the following representation:

Also, as I added the Age_col column, you could categorise the whole thing as Pre-Imperial and Imperial (red or blue). I didn't attach any graphs with that for now, but that works if you add a patch of that colour with a different "zorder" around the dynasties.

For zoomable and pannable graphing, I guess using bokeh or some other similar library for plotting would be better, that way, you can keep it uncluttered and also focus on the parts that make sense?

这篇关于如何使用Python创建历史时间表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 03:15
查看更多