matplotlib 如何从嵌套字典绘制条形图

neekobn8  于 2023-05-23  发布在  其他
关注(0)|答案(4)|浏览(177)

我有一个嵌套的dict,看起来像这样。

{A: {   'apples': 3,
        'bananas':5,
        'oranges':6,
        'kiwis':9},
B: {    'apples': 1,
        'bananas':9,
        'oranges':3,
        'kiwis':1},
C: {    'apples': 6,
        'bananas':9,
        'oranges':3,
        'kiwis':3}}

在我的例子中,A,B,C是一年中的两个月。x轴是月份,即A、B、C等。苹果、香蕉、奇异果和桔子都算在内。我想使用matplotlib绘制一个分组的垂直条形图。它会有一个传说,有三种颜色的苹果,香蕉和橙子。
我只能使用dataframe.plot方法进行绘图:

pd.Dataframe(mydict).T.plot(kind=bar)

我希望能够使用matplotlib绘制相同的图形,这样我就可以管理图形大小并更改条形图的大小等。

wnavrhmk

wnavrhmk1#

pandas的文档说pandas.DataFrame.plot()返回matplotlib.axes.axes对象。因此,基本上,您可以使用与使用matplotlib处理绘图方面相同的方式来处理它。
所以,用你的例子:

# Import libraries 
import pandas as pd
import matplotlib.pyplot as plt

# Create dictionary
plot_dict = {'A': {'Apples': 3,'Bananas':5,'Oranges':6,'Kiwis':9}, 'B': {'Apples': 1,'Bananas':9,'Oranges':3,'Kiwis':1}, 'C': {'Apples': 6,'Bananas':9,'Oranges':3,'Kiwis':3}}

# Plot using pandas built-in function plot()
ax = pd.DataFrame(plot_dict).T.plot.bar(zorder=5)

# Define aspects of the plot using matplotlib
ax.set_ylabel("Quantity")
ax.set_xlabel("Category")
ax.grid(axis='y', color='black', linestyle='-', linewidth=0.3)
ax.legend(loc='lower center', bbox_to_anchor=(0.5, -0.25), ncol=4, edgecolor='1', fontsize=10)
ax.locator_params(axis='y', nbins=12)

plt.savefig(f'./plot_from_nested_dict.svg', bbox_inches='tight')
p4rjhz4m

p4rjhz4m2#

首先,您可以使用figsize参数管理figsize,或者将.plot方法返回的axes存储在dataframe上,因此纯matplotlib解决方案不是唯一的方法。
话虽如此在matplotlib中学习分组条形图的重要内容是要有一个偏移量。每组分组条(例如apple)需要从xtick偏移宽度的函数(例如,宽度 * 2)

d = {"A": {...}, ...}

import matplotlib.pyplot as plt
import numpy as np

# Get the ax object and hardcode a bar width
fig, ax = plt.subplots()

width = 0.05

# Each set of bars (e.g. "bananas") is offset from the xtick so they're grouped
# For example np.arange(3) - width*2 for an offset of negative two bar widths 
ax.bar(np.arange(3) - width*2, [d[j]["apples"] for j in d], width)
ax.bar(np.arange(3) - width, [d[j]["bananas"] for j in d], width)
ax.bar(np.arange(3), [d[j]["oranges"] for j in d], width)
ax.bar(np.arange(3) + width, [d[j]["kiwis"] for j in d], width)

# Labels
ax.set_xticks(np.arange(3))
ax.set_xticklabels(["A", "B", "C"])
7fyelxc5

7fyelxc53#

  • ax = pd.Dataframe(mydict).T.plot(kind='bar', width=0.9, figsize=(12, 8))是绘制字典的最简单方法。
  • pandas.DataFrame.plot使用matplotlib作为默认后端,并返回matplotlib.axes.Axes,因此matplotlib化方法可以正常工作。
  • 查看pandas.DataFrame.plot文档以了解所有格式化参数
  • figsizetitleylabelxlabelgridsubplots等等。
  • ax.调用.legend和其他方法
  • .T转置 Dataframe 。无论索引中的值是什么,都将在x-axis上,列标题将是颜色标签。
  • 有关条形标签注解的其他详细信息,请参见How to add value labels on a bar chartHow to plot and annotate a grouped bar chart
  • matplotlib文档中的Grouped bar chart with labels展示了一个纯粹的matplotlib实现(没有pandas)。
    *python 3.11.2pandas 2.0.1matplotlib 3.7.1中测试
import pandas as pd

d = {'A': {'apples': 3, 'bananas': 5, 'oranges': 6, 'kiwis': 9},
     'B': {'apples': 1, 'bananas': 9, 'oranges': 3, 'kiwis': 1},
     'C': {'apples': 6, 'bananas': 9, 'oranges': 3, 'kiwis': 3}}

# with pandas
df = pd.DataFrame(d)

# custom colors, if desired
color = dict(zip(df.index, ['green', 'yellow', 'orange', 'tan']))

# transpose the dataframe and plot
ax = df.T.plot(kind='bar', rot=0, color=color, title='With pandas',
               figsize=(8, 5), xlabel='Category', ylabel='Quantity')

# cosmetic formatting
ax.legend(bbox_to_anchor=(1, 0.5), loc='center left', frameon=False)
ax.spines[['right', 'top']].set_visible(False)

# iterate through the containers associated with the axes (ax)
for c in ax.containers:
    ax.bar_label(c, fmt=lambda x: f'{x:0.0f}' if x > 0 else '')

df

A  B  C
apples   3  1  6
bananas  5  9  9
oranges  6  3  3
kiwis    9  1  3

df.T

apples  bananas  oranges  kiwis
A       3        5        6      9
B       1        9        3      1
C       6        9        3      3
vhmi4jdf

vhmi4jdf4#

下面是示例代码。请让我知道如果你有任何问题,我会很乐意帮助你。

# libraries
import numpy as np
import matplotlib.pyplot as plt

# set width of bar
barWidth = 0.25

# set height of bar
bars1 = [12, 30, 1, 8, 22]
bars2 = [28, 6, 16, 5, 10]
bars3 = [29, 3, 24, 25, 17]

# Set position of bar on X axis
r1 = np.arange(len(bars1))
r2 = [x + barWidth for x in r1]
r3 = [x + barWidth for x in r2]

# Make the plot
plt.bar(r1, bars1, color='#ff0000', width=barWidth, edgecolor='red', label='Apples')
plt.bar(r2, bars2, color='#FFFF00', width=barWidth, edgecolor='yellow', label='bananas')
plt.bar(r3, bars3, color='#FFA500', width=barWidth, edgecolor='orange', label='oranges')

# Add xticks on the middle of the group bars
plt.xlabel('group', fontweight='bold')
plt.xticks([r + barWidth for r in range(len(bars1))], ['04/01/2019', '04/02/2019', '04/03/2019', '04/04/2019', '04/05/2019'])

# Create legend & Show graphic
plt.legend()
plt.show()

相关问题