Python 将多个绘图放置在特定坐标处的一个大轴上

Python 将多个绘图放置在特定坐标处的一个大轴上,python,matplotlib,subplot,Python,Matplotlib,Subplot,我试图将多个matplotlib子图放到一个大轴中,其中大轴上的记号标签对应于一些参数值,每个子图中的数据都是为这些参数值获取的。举个例子 import matplotlib.pyplot as plt data = {} data[(10, 10)] = [0.45, 0.30, 0.25] data[(10, 20)] = [0.2, 0.5, 0.3] data[(20, 10)] = [0.1, 0.3, 0.6] data[(20, 20)] = [0.6, 0.15, 0.25] d

我试图将多个matplotlib子图放到一个大轴中,其中大轴上的记号标签对应于一些参数值,每个子图中的数据都是为这些参数值获取的。举个例子

import matplotlib.pyplot as plt
data = {}
data[(10, 10)] = [0.45, 0.30, 0.25]
data[(10, 20)] = [0.2, 0.5, 0.3]
data[(20, 10)] = [0.1, 0.3, 0.6]
data[(20, 20)] = [0.6, 0.15, 0.25]
data[(30, 10)] = [0.4, 0.35, 0.25]
data[(30, 20)] = [0.5, 0.1, 0.4]

# x and y coordinates for the big plot
x_coords = list(set([k[0] for k in data.keys()]))
y_coords = list(set([k[1] for k in data.keys()]))

labels = ['Frogs', 'Hogs', 'Dogs']
explode = (0.05, 0.05, 0.05)  #
colors = ['gold', 'beige', 'lightcoral']

fig, axes = plt.subplots(len(y_coords), len(x_coords))

for row_topToDown in range(len(y_coords)):
    row = (len(y_coords)-1) - row_topToDown
    for col in range(len(x_coords)):
        axes[row][col].pie(data[(x_coords[col], y_coords[row_topToDown])], explode=explode, colors = colors, \
        autopct=None, pctdistance = 1.4, \
        shadow=True, startangle=90, radius=0.7, \
        wedgeprops = {'linewidth':1, 'edgecolor':'Black'}
                                     )
        axes[row][col].axis('equal')  # Equal aspect ratio ensures that pie is drawn as a circle.
        axes[row][col].set_title('(' + str(x_coords[col]) + ', ' + str(y_coords[row_topToDown]) + ')')

fig.tight_layout()        
plt.show()
下面是我希望输出的样子: 我看到两种选择:

A.使用单个轴 可以将所有饼图绘制到相同的轴上。使用
center
radius
参数在数据坐标中缩放PIE。这可能如下所示

import matplotlib.pyplot as plt
data = {}
data[(10, 10)] = [0.45, 0.30, 0.25]
data[(10, 20)] = [0.2, 0.5, 0.3]
data[(20, 10)] = [0.1, 0.3, 0.6]
data[(20, 20)] = [0.6, 0.15, 0.25]
data[(30, 10)] = [0.4, 0.35, 0.25]
data[(30, 20)] = [0.5, 0.1, 0.4]

labels = ['Frogs', 'Hogs', 'Dogs']
explode = [.2]*3
colors = ['gold', 'beige', 'lightcoral']
radius = 4
margin = 2

fig, ax = plt.subplots()

for x,y in data.keys():
    d = data[(x,y)]
    ax.pie(d, explode=explode, colors = colors, center=(x,y), 
            shadow=True, startangle=90, radius=radius, 
            wedgeprops = {'linewidth':1, 'edgecolor':'Black'})

    ax.annotate("({},{})".format(x,y), xy = (x, y+radius), 
                xytext = (0,5), textcoords="offset points", ha="center")

ax.set_frame_on(True)
xaxis = list(set([x for x,y in data.keys()]))
yaxis = list(set([y for x,y in data.keys()]))
ax.set(aspect="equal", 
       xlim=(min(xaxis)-radius-margin,max(xaxis)+radius+margin), 
       ylim=(min(yaxis)-radius-margin,max(yaxis)+radius+margin), 
       xticks=xaxis, yticks=yaxis)
fig.tight_layout()        
plt.show()

B.使用插入轴 可以将每个饼图放在其各自的轴上,并将轴定位在数据坐标中。这可以通过使用
mpl\u工具箱、轴网格1、插入定位器、插入轴来实现。与上面的主要区别在于,您可能会使用父轴的不相等方面,并且不可能使用
紧密布局

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes

data = {}
data[(10, 10)] = [0.45, 0.30, 0.25]
data[(10, 20)] = [0.2, 0.5, 0.3]
data[(20, 10)] = [0.1, 0.3, 0.6]
data[(20, 20)] = [0.6, 0.15, 0.25]
data[(30, 10)] = [0.4, 0.35, 0.25]
data[(30, 20)] = [0.5, 0.1, 0.4]


labels = ['Frogs', 'Hogs', 'Dogs']
explode = [.05]*3
colors = ['gold', 'beige', 'lightcoral']
radius = 4
margin = 2

fig, axes = plt.subplots()

for x,y in data.keys():
    d = data[(x,y)]
    ax = inset_axes(axes, "100%", "100%", 
                    bbox_to_anchor=(x-radius, y-radius, radius*2, radius*2),
                    bbox_transform=axes.transData, loc="center")
    ax.pie(d, explode=explode, colors = colors,
            shadow=True, startangle=90,
            wedgeprops = {'linewidth':1, 'edgecolor':'Black'})

    ax.set_title("({},{})".format(x,y))


xaxis = list(set([x for x,y in data.keys()]))
yaxis = list(set([y for x,y in data.keys()]))
axes.set(aspect="equal", 
       xlim=(min(xaxis)-radius-margin,max(xaxis)+radius+margin), 
       ylim=(min(yaxis)-radius-margin,max(yaxis)+radius+margin), 
       xticks=xaxis, yticks=yaxis)
        
plt.show()


关于如何在情节之外添加图例,我建议您参考。以及如何为饼图创建图例,以
也可能感兴趣。

我看到两种选择:

A.使用单个轴 可以将所有饼图绘制到相同的轴上。使用
center
radius
参数在数据坐标中缩放PIE。这可能如下所示

import matplotlib.pyplot as plt
data = {}
data[(10, 10)] = [0.45, 0.30, 0.25]
data[(10, 20)] = [0.2, 0.5, 0.3]
data[(20, 10)] = [0.1, 0.3, 0.6]
data[(20, 20)] = [0.6, 0.15, 0.25]
data[(30, 10)] = [0.4, 0.35, 0.25]
data[(30, 20)] = [0.5, 0.1, 0.4]

labels = ['Frogs', 'Hogs', 'Dogs']
explode = [.2]*3
colors = ['gold', 'beige', 'lightcoral']
radius = 4
margin = 2

fig, ax = plt.subplots()

for x,y in data.keys():
    d = data[(x,y)]
    ax.pie(d, explode=explode, colors = colors, center=(x,y), 
            shadow=True, startangle=90, radius=radius, 
            wedgeprops = {'linewidth':1, 'edgecolor':'Black'})

    ax.annotate("({},{})".format(x,y), xy = (x, y+radius), 
                xytext = (0,5), textcoords="offset points", ha="center")

ax.set_frame_on(True)
xaxis = list(set([x for x,y in data.keys()]))
yaxis = list(set([y for x,y in data.keys()]))
ax.set(aspect="equal", 
       xlim=(min(xaxis)-radius-margin,max(xaxis)+radius+margin), 
       ylim=(min(yaxis)-radius-margin,max(yaxis)+radius+margin), 
       xticks=xaxis, yticks=yaxis)
fig.tight_layout()        
plt.show()

B.使用插入轴 可以将每个饼图放在其各自的轴上,并将轴定位在数据坐标中。这可以通过使用
mpl\u工具箱、轴网格1、插入定位器、插入轴来实现。与上面的主要区别在于,您可能会使用父轴的不相等方面,并且不可能使用
紧密布局

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes

data = {}
data[(10, 10)] = [0.45, 0.30, 0.25]
data[(10, 20)] = [0.2, 0.5, 0.3]
data[(20, 10)] = [0.1, 0.3, 0.6]
data[(20, 20)] = [0.6, 0.15, 0.25]
data[(30, 10)] = [0.4, 0.35, 0.25]
data[(30, 20)] = [0.5, 0.1, 0.4]


labels = ['Frogs', 'Hogs', 'Dogs']
explode = [.05]*3
colors = ['gold', 'beige', 'lightcoral']
radius = 4
margin = 2

fig, axes = plt.subplots()

for x,y in data.keys():
    d = data[(x,y)]
    ax = inset_axes(axes, "100%", "100%", 
                    bbox_to_anchor=(x-radius, y-radius, radius*2, radius*2),
                    bbox_transform=axes.transData, loc="center")
    ax.pie(d, explode=explode, colors = colors,
            shadow=True, startangle=90,
            wedgeprops = {'linewidth':1, 'edgecolor':'Black'})

    ax.set_title("({},{})".format(x,y))


xaxis = list(set([x for x,y in data.keys()]))
yaxis = list(set([y for x,y in data.keys()]))
axes.set(aspect="equal", 
       xlim=(min(xaxis)-radius-margin,max(xaxis)+radius+margin), 
       ylim=(min(yaxis)-radius-margin,max(yaxis)+radius+margin), 
       xticks=xaxis, yticks=yaxis)
        
plt.show()


关于如何在情节之外添加图例,我建议您参考。以及如何为饼图创建图例,以

也可能有兴趣。

我认为你需要的每一个信息都在那篇文章中。目的是在每个子地块内放置一个较小的绘图,这与我所希望的不完全一样,也就是说,将所有子地块放置在一个较大的轴内,其中每个子地块对应于该大框架上的特定xy坐标。特别是,我很难在较大的框架上设置记号和记号标签,以对应于每个子地块。我认为您需要的每个信息都在该帖子中。目的是在每个子地块内放置一个较小的绘图,这与我想要的不完全一样,即,将所有子地块放置在一个较大的轴内,其中每个子批次对应于该大框架上的特定xy坐标。特别是,我很难在较大的框架上设置记号和记号标签,以对应于每个子图。由于您使用的是radius,所以这两种方法对于饼图都非常有效。是否有更通用的解决方案适用于半径不相关的任何类型的图形(例如直线图)?当然,只需将
radius
重命名为其他名称即可。对不起。我可能在谈论一些我不太清楚的非常明显的事情。我的意思是radius是函数饼图的一个关键字参数,它决定饼图的大小,但我们可能没有这样一个参数来设置其他打印类型(如线性)的大小。好的,显然您不能使用解决方案a。对于解决方案B,
饼图
中没有定义
radius
。因此,您可以忽略它。是否可以通过使用“添加”轴和“设置”位置而不是使用“插入”轴来解决方法B无法使用紧密布局的问题?这两种方法对于饼图都非常有效,因为您使用的是半径。是否有更通用的解决方案适用于半径不相关的任何类型的图形(例如直线图)?当然,只需将
radius
重命名为其他名称即可。对不起。我可能在谈论一些我不太清楚的非常明显的事情。我的意思是radius是函数饼图的一个关键字参数,它决定饼图的大小,但我们可能没有这样一个参数来设置其他打印类型(如线性)的大小。好的,显然您不能使用解决方案a。对于解决方案B,
饼图
中没有定义
radius
。因此您可以忽略它。是否可以通过使用“添加”轴和“设置”位置而不是使用“插入”轴来解决方法B不能使用紧密布局的问题?