所以我在这里看到了一些有点帮助的答案,但是我的数据集比以前回答的要大。要了解我正在使用的内容,here's a link to the full dataset。我已经在此link中找到了一个尝试解决方案的图片: 。
问题在于1.这很难理解2.我不知道如何将其展平,使其看起来像传统的时间表。当我尝试使用更大的片段时,问题变得更加明显,例如这个片段基本上是不可读的: 这是我用来生成这两个代码的代码(我刚刚修改了包含的代码,以便更改使用整个数据集的哪个部分)。
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')
这段代码是半工作的,但我更喜欢这些条纹要么更接近,要么颜色不同,并且都在相同的y值上。我感谢任何和所有的帮助。我一直试图解决这个问题大约两个星期了,我正在打砖墙。
答案 0 :(得分:2)
我不知道你是否已经解决了这个问题,但是,从我到目前为止从你的代码中看到的以及(也从 Evgeny 的代码中借用)你的要求,你有不同级别的水平的唯一原因bar 是因为您已将 matplotlib (matplotlib.pyplot.barh(y, width, height=0.8, left=None, *, align='center', **kwargs
) 的 barh 的标量 y 定义为一个范围。因此,每个连续的堆叠条都在单独的级别上列出。
所以,我冒昧地下载了您的数据集并稍微玩了一下代码。
我从谷歌数据集创建了一个数据框,并为每个王朝(Dynasty_col 列)和年龄(Age_col 列)分配了一个 matplotlib CSS 颜色(这不是必需的,但是,我发现这更易于管理可视化):
接下来,我主要保留了您/Evgeny 的代码已经显示的内容,并进行了一些小改动:
event = data_set_xia['EnglishName']
begin = data_set_xia['Start']
end = data_set_xia['Finish']
length = data_set_xia['Length']
这里我用垂直线添加了一个命名级别(你可以加长或缩短数组[-2, 2, -1, 1]以获得不同级别的标签):
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))
这里我基本上在同一个 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('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)
我在标签上使用了一些垂直线,标签与级别相关联以创建绘图。
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()
现在显然,条目的数量越长,图表变得越忙和越混乱,它开始看起来有点难看,但它仍然清晰易读。此外,代码并不“完美”,我会稍微清理一下并更改一些命令选项,例如 barh 参数中的 color,但它现在可以使用。
为了替代表示,我添加了按时间交错表示不同朝代的代码,因为一些朝代相互重叠:
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()
最后一部分是仓促完成的,所以代码不是最简洁的,但我在这里唯一改变的是根据数据子集中的朝代更新 barh 的 y 标量我正在考虑。为了便于阅读,我修改了级别和字体大小,您可以使用数字和代码来获得适当的表示。
此外,当我添加了 Age_col 列时,您可以将整个事物归类为前帝国和帝国(红色或蓝色)。我暂时没有附上任何图表,但如果你在王朝周围添加一个具有不同“zorder”的那种颜色的补丁,那就行了。
对于可缩放和可平移的图形,我想使用散景或其他类似的库进行绘图会更好,这样,您可以保持整洁并专注于有意义的部分?
答案 1 :(得分:1)
这是复制原始图的代码,在问题中可以预期这样的事情,将允许更多时间来回答问题(而不是重新创建它)。
import pandas as pd
import matplotlib.pyplot as plt
xia = pd.DataFrame([['Da Yu', -2207, -2197],
['Qi', -2197, -2188],
['Tai Kang', -2188, -2159]],
columns=['EnglishName', 'Start', 'Finish'])
event = xia['EnglishName']
begin = xia['Start']
end = xia['Finish']
length = xia['Finish'] - xia['Start']
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(3):
plt.text(begin.iloc[i] + length.iloc[i]/2,
i+.25, event.iloc[i],
ha='center', fontsize = '12')
委屈(解决下一步做什么):
问题在于 这很难读懂 我不知道如何压扁它,看起来像传统的时间表。当我尝试使用更大的片段时,问题变得更加明显
我更喜欢这些酒吧是靠得更近还是颜色不同而且都是相同的y值。
设计很难用语言表达。如果你放一行(例如,使用此plt.barh([1 for _ in begin], (end-begin)-0.5, .3, left=begin)
),文本将重叠甚至更难以理解。
这是一个重现水平时间轴的小代码:
plt.figure(figsize=(4,2))
plt.ylim(0.5, 1.5)
plt.yticks(range(len(begin)), "")
# 0.25 is a stub, it controls for white separator
plt.barh([1 for _ in begin], (end-begin)-0.25, .3, left=begin)
但是你希望将名字放在哪里?
如果你想要不同的颜色,需要一些关于颜色的规则。程序员会说你需要一个更好的任务规范。
答案 2 :(得分:0)
我做了类似的情景喜剧演替图表的类似图表。代码有点幼稚(placed on github),但在遇到你的问题时,我很惊讶这对于做类似可视化的人来说仍然是一个问题。我希望可能有专门的历史图表库。