Matplotlib 堆积条形图:需要交换 x 和高度
Matplotlib stacked bar plot: need to swap x and height
我正在查看一些世界生态足迹数据,我想为每种类型的足迹制作堆叠条形图,其中堆叠在一起的值是相同的,但适用于不同的国家/地区。所以我开始使用其中的 2 个脚印来让一些东西工作。
这就是我的工作(有点):
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Create DataFrame from CSV file
df = pd.read_csv('countries.csv')
# Slice Series out of DF
cropFoot = df['Cropland Footprint']
grazeFoot = df['Grazing Footprint']
# Convert Series to list
cropFoot = list(cropFoot)
grazeFoot = list(grazeFoot)
X = range(163) # the lists have 163 entries
plt.bar(X, height=cropFoot)
plt.bar(X, height=grazeFoot, bottom = cropFoot)
plt.show()
生成以下图:
我有 5 个单独的足迹要显示在 x-axis 上,以便每个国家/地区的足迹数据堆叠在一起。本质上,现在 x-axis 显示了所有 163 个国家/地区的 2 个足迹。我想要相反的。所以我想要 5 个条形图,每个条形图上堆叠 163 个国家/地区。
类似这样的东西(但是堆叠了 163 个,而不是 7 个):
不出所料,仅仅交换 X 和高度……是行不通的。结果根本没有任何意义:
plt.bar(cropFoot, height=X)
plt.bar(grazeFoot, height=X, bottom = cropFoot)
plt.show()
看起来像这样:
关于如何正确扭转这种情况有什么建议吗? This is the dataset I'm using,来自 Kaggle。
由于您已经在使用数据框,您可能想尝试提供的 bar plot 方法,它更容易使用。要堆叠,只需要设置参数stacked=True
。但是,堆叠的是列名,因此您必须先转置数据框。它可能看起来像这样:
footprints = ['Cropland Footprint', 'Grazing Footprint', ...] # fill with other footprints
data = df[footprints].T
data.plot.bar(stacked=True, legend=False) # you probably don't want a legend with 163 countries
举个例子:
df = pd.DataFrame(
np.arange(200).reshape(40, 5),
index=[f'i{x}' for x in range(40)],
columns=[f'c{x}' for x in range(5)]
)
df.T.plot.bar(stacked=True, legend=False)
我认为@busybear 使用数据框条形图的答案更好,但我认为显示使用 matplotlib.pyplot.bar
的解决方案可能是合适的,因为这是问题的完整性。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Creates a randomized set of data to use for demonstration
n = 163
m = 5
footprints = np.zeros((m, n))
for ii in range(n):
for jj in range(m):
footprints[jj][ii] = random.random()*10
# This line is unnecessary for the example, it is purely for plot aesthetic
fig = plt.figure(figsize=(5, 5), dpi=200)
# colors can be replaced with any list of colors of any length >= 1
colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
bottom = np.zeros(5)
for ii in range(1, n):
for jj in range(m):
plt.bar(jj, height=footprints[jj][ii], bottom=bottom[jj],
color=colors[ii % len(colors)])
bottom[jj] = bottom[jj] + footprints[jj][ii]
plt.show()
我正在查看一些世界生态足迹数据,我想为每种类型的足迹制作堆叠条形图,其中堆叠在一起的值是相同的,但适用于不同的国家/地区。所以我开始使用其中的 2 个脚印来让一些东西工作。
这就是我的工作(有点):
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Create DataFrame from CSV file
df = pd.read_csv('countries.csv')
# Slice Series out of DF
cropFoot = df['Cropland Footprint']
grazeFoot = df['Grazing Footprint']
# Convert Series to list
cropFoot = list(cropFoot)
grazeFoot = list(grazeFoot)
X = range(163) # the lists have 163 entries
plt.bar(X, height=cropFoot)
plt.bar(X, height=grazeFoot, bottom = cropFoot)
plt.show()
生成以下图:
我有 5 个单独的足迹要显示在 x-axis 上,以便每个国家/地区的足迹数据堆叠在一起。本质上,现在 x-axis 显示了所有 163 个国家/地区的 2 个足迹。我想要相反的。所以我想要 5 个条形图,每个条形图上堆叠 163 个国家/地区。
类似这样的东西(但是堆叠了 163 个,而不是 7 个):
不出所料,仅仅交换 X 和高度……是行不通的。结果根本没有任何意义:
plt.bar(cropFoot, height=X)
plt.bar(grazeFoot, height=X, bottom = cropFoot)
plt.show()
看起来像这样:
关于如何正确扭转这种情况有什么建议吗? This is the dataset I'm using,来自 Kaggle。
由于您已经在使用数据框,您可能想尝试提供的 bar plot 方法,它更容易使用。要堆叠,只需要设置参数stacked=True
。但是,堆叠的是列名,因此您必须先转置数据框。它可能看起来像这样:
footprints = ['Cropland Footprint', 'Grazing Footprint', ...] # fill with other footprints
data = df[footprints].T
data.plot.bar(stacked=True, legend=False) # you probably don't want a legend with 163 countries
举个例子:
df = pd.DataFrame(
np.arange(200).reshape(40, 5),
index=[f'i{x}' for x in range(40)],
columns=[f'c{x}' for x in range(5)]
)
df.T.plot.bar(stacked=True, legend=False)
我认为@busybear 使用数据框条形图的答案更好,但我认为显示使用 matplotlib.pyplot.bar
的解决方案可能是合适的,因为这是问题的完整性。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Creates a randomized set of data to use for demonstration
n = 163
m = 5
footprints = np.zeros((m, n))
for ii in range(n):
for jj in range(m):
footprints[jj][ii] = random.random()*10
# This line is unnecessary for the example, it is purely for plot aesthetic
fig = plt.figure(figsize=(5, 5), dpi=200)
# colors can be replaced with any list of colors of any length >= 1
colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
bottom = np.zeros(5)
for ii in range(1, n):
for jj in range(m):
plt.bar(jj, height=footprints[jj][ii], bottom=bottom[jj],
color=colors[ii % len(colors)])
bottom[jj] = bottom[jj] + footprints[jj][ii]
plt.show()