Поместите несколько графиков в одну большую ось в определенных координатах - PullRequest
0 голосов
/ 20 ноября 2018

Я пытаюсь поместить несколько вспомогательных участков 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()

и вот как я бы хотел, чтобы результат выглядел так: enter image description here

1 Ответ

0 голосов
/ 20 ноября 2018

Я вижу два варианта:

A.использовать одну ось

Вы можете построить все круговые диаграммы для одинаковых осей.Используйте аргумент center и radius для масштабирования пирогов в координатах данных.Это может выглядеть следующим образом.

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()

enter image description here

B.использовать вставные оси

Вы можете поместить каждый круг в свои оси и расположить оси в координатах данных.Этому способствует использование mpl_toolkits.axes_grid1.inset_locator.inset_axes.Основное отличие от вышеизложенного состоит в том, что вы можете использовать неравный аспект родительских осей и что невозможно использовать tight_layout.

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()

enter image description here


Как разместить легенду вне сюжета, я бы отослал вас к Как убрать легенду из сюжета .И для того, как создать легенду для круговой диаграммы в Как добавить легенду в круговую диаграмму matplotlib?
Также Python - Легенда может перекрывать круговую диаграмму может представлять интерес.

...