【问题标题】:Equal spacing between pie charts of different sizes in matplotlibmatplotlib中不同大小的饼图间距相等
【发布时间】:2022-01-07 20:43:52
【问题描述】:

我无法在不同大小的饼图之间设置相等的间距。 5 个正确排列成一排,但相邻馅饼的轮廓之间的距离不相等。我尝试了以下代码的许多缩写,它们都没有对输出产生很大影响(见图):

#代码:

import matplotlib.pyplot as plt
import pandas as pd
labels = 'Verkehr', 'Maschinen und Motoren', 'Feuerungen', 'Industrie / Gewerbe', 'Land- und Forstwirtschaft'
sizesax1 = [108295, 10107, 7220, 11551, 7220]
sizesax2 = [77882, 6676, 6676, 13351, 6676]
sizesax3 = [55652, 4417, 6184, 15900, 6184]
sizesax4 = [36327, 2642, 4632, 16512, 5944]
sizesax5 = [18781, 1409, 3287, 1878, 4695]

fig, (ax1, ax2, ax3, ax4, ax5) = plt.subplots(1, 5, figsize =(20,4))
ax1.pie(sizesax1, startangle=0, colors = ('red', 'darkblue', 'orange', 'yellow', 'green'), radius=1*4)
ax2.pie(sizesax2, startangle=0, colors = ('red', 'darkblue', 'orange', 'yellow', 'green'), radius=.77*4)
ax3.pie(sizesax3, startangle=0, colors = ('red', 'darkblue', 'orange', 'yellow', 'green'), radius=.61*4)
ax4.pie(sizesax4, startangle=0, colors = ('red', 'darkblue', 'orange', 'yellow', 'green'), radius=.46*4)
ax5.pie(sizesax5, startangle=0, colors = ('red', 'darkblue', 'orange', 'yellow', 'green'), radius=.33*4)

我尝试了一些补充:

fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=1, hspace=None)

fig.tight_layout()
#giving me this error message:
/srv/conda/envs/notebook/lib/python3.7/site-packages/ipykernel_launcher.py:17: UserWarning:
Tight layout not applied. The bottom and top margins cannot be made large enough to
accommodate all axes decorations.

还有一些其他的。

非常感谢您阅读本文!我是 python 的一个完整的初学者,只是设法达到你在这张图片中看到的:

enter image description here

【问题讨论】:

  • 这个定义有点不明确。您是否希望馅饼之间的空白相同,或者您是否希望中心之间的距离相同?还有半径需要有多精确?

标签: python-3.x pandas matplotlib jupyter-notebook pie-chart


【解决方案1】:

不清楚它需要什么。我假设它是以下图像:

从根本上说,问题在于饼图需要一个正方形的纵横比,而这不是由一行子图提供的。

最简单的解决方案是只创建一个地块并在那里绘制多个中心不同的饼图。比如:

import matplotlib.pyplot as plt

sizes = [ [108295, 10107, 7220, 11551, 7220],
          [77882, 6676, 6676, 13351, 6676],
          [55652, 4417, 6184, 15900, 6184],
          [36327, 2642, 4632, 16512, 5944],
          [18781, 1409, 3287, 1878, 4695]]

colors = ('red', 'darkblue', 'orange', 'yellow', 'green')

R = 4

radius = [R*i for i in [1.0, 0.77, 0.61, 0.46, 0.33] ]
wid = sum(radius)*2
hei = R*2

fig, ax = plt.subplots(figsize =(wid,hei))
fig.subplots_adjust(left = 0, right = 1, bottom = 0, top = 1)

y = R
x = 0

for i in range(5):

    x += radius[i]
    ax.pie(sizes[i], startangle = 0, colors = colors,
           radius = radius[i], center = (x,y) )
    x += radius[i]

ax.set(xlim =(0,x), ylim=(0,R*2))

plt.savefig("aaa.png")

请注意,我的图形纵横比不是问题的 (20,4),这不适用于我解释预期结果的方式。

但可能需要将它们放在不同的轴上。如果是这样,想法是:

  1. 使用 gridspec 创建一个包含 5 列的单行并提供比率,以便它们对应于所需的半径。

  2. 在左侧槽中绘制较大的饼图。

  3. 在所有剩余的槽中,使用一个子网格,分为三个(子)槽的列。

  4. 设置高度比,使中间的最终以正方形的纵横比结束。

  5. 在中间的插槽中绘制馅饼。

我们开始吧:

import matplotlib.pyplot as plt


sizes = [ [108295, 10107, 7220, 11551, 7220],
          [77882, 6676, 6676, 13351, 6676],
          [55652, 4417, 6184, 15900, 6184],
          [36327, 2642, 4632, 16512, 5944],
          [18781, 1409, 3287, 1878, 4695]]

colors = ('red', 'darkblue', 'orange', 'yellow', 'green')

R = 4

radius = [R*i for i in [1.0, 0.77, 0.61, 0.46, 0.33] ]
wid = sum(radius)*2
hei = R*2
ratios = [i/radius[0] for i in radius] # for gridspec

fig = plt.figure(figsize =(wid,hei))
gs = fig.add_gridspec(1, 5,
                      width_ratios = ratios,
                      wspace=0, left = 0, right = 1, bottom = 0, top = 1)

ax = fig.add_subplot(gs[0,0])
ax.pie(sizes[0], startangle = 0, colors = colors, radius = 1 )
ax.set(xlim=(-1,1) ,ylim=(-1,1))
    
for i in range(1,5):

    mid = ratios[i]/sum(ratios)*wid
    inrat = [(hei-mid)/2, mid, (hei-mid)/2]
    ings = gs[0,i].subgridspec(3, 1, hspace=0,
                               height_ratios = inrat)
    
    ax = fig.add_subplot(ings[1,0])
    ax.pie(sizes[i], startangle = 0, colors = colors, radius = 1 )
    ax.set(xlim=(-1,1), ylim=(-1,1))

plt.savefig("aaa.png")

【讨论】: