如何加载和转换数据以绘制水平堆叠条形图?

时间:2020-07-28 13:34:39

标签: python pandas matplotlib data-transform

  • 我将离散分布示例用作matplotlib Discrete distribution as horizontal bar chart上的水平条形图示例,以创建一个图表,显示在什罗普郡选举2017中的投票份额。

  • 但是,由于我不知道如何处理数据,因此不得不在程序中手动输入数据,这显然是我自己的无知。

  • 我将相关数据保存在CSV文件中,因此可以将其作为数据框加载。

    • CSV每个病房都有一行,其中每一方(托里,劳工党,劳工,格林,独立)有63列和%的投票栏,因此有5个实质性列。
  • 我希望获得有关如何更改数据形式的建议,以使其类似于此图表的输入。

  • 我不确定它是什么,但似乎可能是具有键和值的字典类型:

我的数据部分读取:

category_names = ['Labour', 'LD', 'Indep', 'Green', 'Tory']
results = {'Abbey': [16, 56, 4,0, 24],
           'Albrighton': [0, 0, 32, 0, 68],
           'Alveley & Claverley': [0, 25, 0, 0, 75],
           'Bagley': [30, 30, 0, 0, 40],
           'Battlefield': [34, 0, 0, 9, 57],
           'Bayston Hill, Column & Sutton': [53, 4, 3, 7, 33],
           'Belle Vue': [43,28,0,5,24]}
  • 当我将其作为熊猫数据框输入时,我试图直接从csv文件中获取要格式化的数据。

  • 已经尝试过values方法和to_dict方法,尽管它们获得的数据看起来很相似,但它们并不完全正确。

    • 我认为有必要将数据分为键和值,但这正是我所学知识所能达到的极限。

1 个答案:

答案 0 :(得分:0)

选项1:以'Party'作为y轴

  • 使用来自OP的resultscategory_names数据
import pandas as pd
import matplotlib.pyplot as plt

# plt configuration parameters
plt.style.use('seaborn')
plt.rcParams['figure.figsize'] = (16.0, 10.0)

# setup dataframe using the dict provided in the OP
df = pd.DataFrame(results, index=category_names)

# display(df)
        Abbey  Albrighton  Alveley & Claverley  Bagley  Battlefield  Bayston Hill, Column & Sutton  Belle Vue
Labour     16           0                    0      30           34                             53         43
LD         56           0                   25      30            0                              4         28
Indep       4          32                    0       0            0                              3          0
Green       0           0                    0       0            9                              7          5
Tory       24          68                   75      40           57                             33         24

# plot 
ax = df.plot.barh(stacked=True, cmap='tab10', figsize=(16, 10))

# annotations:
for p in ax.patches:
    left, bottom, width, height = p.get_bbox().bounds
    if width > 0:
         ax.annotate(f'{width:0.0f}', xy=(left+width/2, bottom+height/2), ha='center', va='center')

enter image description here

选项2:以'Ward'作为y轴

  • 使用pandas.DataFrame.T交换IndexColumns
    • 'Ward'现在将成为索引,'Party'将成为列
# using df from Option 1

# transpose df so Party is the in the columns and Ward is the index
dft = df.T

# display(dft)
                               Labour  LD  Indep  Green  Tory
Abbey                              16  56      4      0    24
Albrighton                          0   0     32      0    68
Alveley & Claverley                 0  25      0      0    75
Bagley                             30  30      0      0    40
Battlefield                        34   0      0      9    57
Bayston Hill, Column & Sutton      53   4      3      7    33
Belle Vue                          43  28      0      5    24

# plot
ax = dft.plot.barh(stacked=True, figsize=(16, 10))

plt.legend(loc='center left', bbox_to_anchor=(1.0, 0.5))

# annotations:
for p in ax.patches:
    left, bottom, width, height = p.get_bbox().bounds
    if width > 0:
         ax.annotate(f'{width:0.0f}', xy=(left+width/2, bottom+height/2), ha='center', va='center')

enter image description here