Place multiple plots into one big axis at specific coordinates












0















I am trying to put multiple matplotlib subplots into a big axis, where tick labels on the big axis correspond to some parameter values for which the data in each subplot has been obtained. Here's an example,



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


and here's how I'd like the output to look like:
enter image description here










share|improve this question

























  • I think every information you need is here

    – user8408080
    Nov 19 '18 at 21:42











  • In that post the aim is to place a smaller plot inside each subplot, which is not exactly what I want, i.e., to place all subplots inside a bigger axis, wherein each subplot corresponds to a specific xy-coordinate on that big frame. Particularly, I have a hard time setting the ticks and tick labels on the bigger frame to correspond to each subplot.

    – user3076813
    Nov 20 '18 at 0:29
















0















I am trying to put multiple matplotlib subplots into a big axis, where tick labels on the big axis correspond to some parameter values for which the data in each subplot has been obtained. Here's an example,



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


and here's how I'd like the output to look like:
enter image description here










share|improve this question

























  • I think every information you need is here

    – user8408080
    Nov 19 '18 at 21:42











  • In that post the aim is to place a smaller plot inside each subplot, which is not exactly what I want, i.e., to place all subplots inside a bigger axis, wherein each subplot corresponds to a specific xy-coordinate on that big frame. Particularly, I have a hard time setting the ticks and tick labels on the bigger frame to correspond to each subplot.

    – user3076813
    Nov 20 '18 at 0:29














0












0








0








I am trying to put multiple matplotlib subplots into a big axis, where tick labels on the big axis correspond to some parameter values for which the data in each subplot has been obtained. Here's an example,



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


and here's how I'd like the output to look like:
enter image description here










share|improve this question
















I am trying to put multiple matplotlib subplots into a big axis, where tick labels on the big axis correspond to some parameter values for which the data in each subplot has been obtained. Here's an example,



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


and here's how I'd like the output to look like:
enter image description here







python matplotlib subplot






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 30 '18 at 21:17







user3076813

















asked Nov 19 '18 at 21:29









user3076813user3076813

6928




6928













  • I think every information you need is here

    – user8408080
    Nov 19 '18 at 21:42











  • In that post the aim is to place a smaller plot inside each subplot, which is not exactly what I want, i.e., to place all subplots inside a bigger axis, wherein each subplot corresponds to a specific xy-coordinate on that big frame. Particularly, I have a hard time setting the ticks and tick labels on the bigger frame to correspond to each subplot.

    – user3076813
    Nov 20 '18 at 0:29



















  • I think every information you need is here

    – user8408080
    Nov 19 '18 at 21:42











  • In that post the aim is to place a smaller plot inside each subplot, which is not exactly what I want, i.e., to place all subplots inside a bigger axis, wherein each subplot corresponds to a specific xy-coordinate on that big frame. Particularly, I have a hard time setting the ticks and tick labels on the bigger frame to correspond to each subplot.

    – user3076813
    Nov 20 '18 at 0:29

















I think every information you need is here

– user8408080
Nov 19 '18 at 21:42





I think every information you need is here

– user8408080
Nov 19 '18 at 21:42













In that post the aim is to place a smaller plot inside each subplot, which is not exactly what I want, i.e., to place all subplots inside a bigger axis, wherein each subplot corresponds to a specific xy-coordinate on that big frame. Particularly, I have a hard time setting the ticks and tick labels on the bigger frame to correspond to each subplot.

– user3076813
Nov 20 '18 at 0:29





In that post the aim is to place a smaller plot inside each subplot, which is not exactly what I want, i.e., to place all subplots inside a bigger axis, wherein each subplot corresponds to a specific xy-coordinate on that big frame. Particularly, I have a hard time setting the ticks and tick labels on the bigger frame to correspond to each subplot.

– user3076813
Nov 20 '18 at 0:29












1 Answer
1






active

oldest

votes


















2














I see two options:



A. use a single axes



You may plot all pie charts to the same axes. Use the center and radius argument to scale the pies in data coordinates. This could look as follows.



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. use inset axes



You can put each pie in its own axes and position the axes in data coordinates. This is facilitated by using mpl_toolkits.axes_grid1.inset_locator.inset_axes. The main difference to the above is that you may use a non-equal aspect of the parent axes, and that it's not possible to use 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





For how to put a legend outside the plot, I would refer you to How to put the legend out of the plot. And for how to create a legend for a pie chart to How to add a legend to matplotlib pie chart?

Also Python - Legend overlaps with the pie chart may be of interest.






share|improve this answer


























  • Both of your methods work perfectly fine for pie charts since you're working with radius. Is there a more general solution that works for any type of graph where radius is irrelevant (e.g., line plots)?

    – user3076813
    Nov 26 '18 at 21:40











  • Sure, just rename radius to something else.

    – ImportanceOfBeingErnest
    Nov 26 '18 at 21:43











  • Sorry. I might be talking about something very obvious that is not very clear to me. I meant radius is a keyword argument for function pie, which determines the size of the pie, but we may not have such a single parameter to set the size for other plot types (like a linear).

    – user3076813
    Nov 26 '18 at 21:53











  • Ok, obviously you cannot use the solution A. For solution B. there is no radius defined inside of pie. Hence you can just ignore it.

    – ImportanceOfBeingErnest
    Nov 26 '18 at 21:54











  • Is it possible to get around the problem of not being able to use tight_layout for Method B through using add_axes and set_position instead of using inset_axes?

    – user3076813
    Nov 27 '18 at 18:31











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53382914%2fplace-multiple-plots-into-one-big-axis-at-specific-coordinates%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














I see two options:



A. use a single axes



You may plot all pie charts to the same axes. Use the center and radius argument to scale the pies in data coordinates. This could look as follows.



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. use inset axes



You can put each pie in its own axes and position the axes in data coordinates. This is facilitated by using mpl_toolkits.axes_grid1.inset_locator.inset_axes. The main difference to the above is that you may use a non-equal aspect of the parent axes, and that it's not possible to use 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





For how to put a legend outside the plot, I would refer you to How to put the legend out of the plot. And for how to create a legend for a pie chart to How to add a legend to matplotlib pie chart?

Also Python - Legend overlaps with the pie chart may be of interest.






share|improve this answer


























  • Both of your methods work perfectly fine for pie charts since you're working with radius. Is there a more general solution that works for any type of graph where radius is irrelevant (e.g., line plots)?

    – user3076813
    Nov 26 '18 at 21:40











  • Sure, just rename radius to something else.

    – ImportanceOfBeingErnest
    Nov 26 '18 at 21:43











  • Sorry. I might be talking about something very obvious that is not very clear to me. I meant radius is a keyword argument for function pie, which determines the size of the pie, but we may not have such a single parameter to set the size for other plot types (like a linear).

    – user3076813
    Nov 26 '18 at 21:53











  • Ok, obviously you cannot use the solution A. For solution B. there is no radius defined inside of pie. Hence you can just ignore it.

    – ImportanceOfBeingErnest
    Nov 26 '18 at 21:54











  • Is it possible to get around the problem of not being able to use tight_layout for Method B through using add_axes and set_position instead of using inset_axes?

    – user3076813
    Nov 27 '18 at 18:31
















2














I see two options:



A. use a single axes



You may plot all pie charts to the same axes. Use the center and radius argument to scale the pies in data coordinates. This could look as follows.



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. use inset axes



You can put each pie in its own axes and position the axes in data coordinates. This is facilitated by using mpl_toolkits.axes_grid1.inset_locator.inset_axes. The main difference to the above is that you may use a non-equal aspect of the parent axes, and that it's not possible to use 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





For how to put a legend outside the plot, I would refer you to How to put the legend out of the plot. And for how to create a legend for a pie chart to How to add a legend to matplotlib pie chart?

Also Python - Legend overlaps with the pie chart may be of interest.






share|improve this answer


























  • Both of your methods work perfectly fine for pie charts since you're working with radius. Is there a more general solution that works for any type of graph where radius is irrelevant (e.g., line plots)?

    – user3076813
    Nov 26 '18 at 21:40











  • Sure, just rename radius to something else.

    – ImportanceOfBeingErnest
    Nov 26 '18 at 21:43











  • Sorry. I might be talking about something very obvious that is not very clear to me. I meant radius is a keyword argument for function pie, which determines the size of the pie, but we may not have such a single parameter to set the size for other plot types (like a linear).

    – user3076813
    Nov 26 '18 at 21:53











  • Ok, obviously you cannot use the solution A. For solution B. there is no radius defined inside of pie. Hence you can just ignore it.

    – ImportanceOfBeingErnest
    Nov 26 '18 at 21:54











  • Is it possible to get around the problem of not being able to use tight_layout for Method B through using add_axes and set_position instead of using inset_axes?

    – user3076813
    Nov 27 '18 at 18:31














2












2








2







I see two options:



A. use a single axes



You may plot all pie charts to the same axes. Use the center and radius argument to scale the pies in data coordinates. This could look as follows.



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. use inset axes



You can put each pie in its own axes and position the axes in data coordinates. This is facilitated by using mpl_toolkits.axes_grid1.inset_locator.inset_axes. The main difference to the above is that you may use a non-equal aspect of the parent axes, and that it's not possible to use 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





For how to put a legend outside the plot, I would refer you to How to put the legend out of the plot. And for how to create a legend for a pie chart to How to add a legend to matplotlib pie chart?

Also Python - Legend overlaps with the pie chart may be of interest.






share|improve this answer















I see two options:



A. use a single axes



You may plot all pie charts to the same axes. Use the center and radius argument to scale the pies in data coordinates. This could look as follows.



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. use inset axes



You can put each pie in its own axes and position the axes in data coordinates. This is facilitated by using mpl_toolkits.axes_grid1.inset_locator.inset_axes. The main difference to the above is that you may use a non-equal aspect of the parent axes, and that it's not possible to use 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





For how to put a legend outside the plot, I would refer you to How to put the legend out of the plot. And for how to create a legend for a pie chart to How to add a legend to matplotlib pie chart?

Also Python - Legend overlaps with the pie chart may be of interest.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 30 '18 at 21:18

























answered Nov 20 '18 at 0:30









ImportanceOfBeingErnestImportanceOfBeingErnest

127k12131207




127k12131207













  • Both of your methods work perfectly fine for pie charts since you're working with radius. Is there a more general solution that works for any type of graph where radius is irrelevant (e.g., line plots)?

    – user3076813
    Nov 26 '18 at 21:40











  • Sure, just rename radius to something else.

    – ImportanceOfBeingErnest
    Nov 26 '18 at 21:43











  • Sorry. I might be talking about something very obvious that is not very clear to me. I meant radius is a keyword argument for function pie, which determines the size of the pie, but we may not have such a single parameter to set the size for other plot types (like a linear).

    – user3076813
    Nov 26 '18 at 21:53











  • Ok, obviously you cannot use the solution A. For solution B. there is no radius defined inside of pie. Hence you can just ignore it.

    – ImportanceOfBeingErnest
    Nov 26 '18 at 21:54











  • Is it possible to get around the problem of not being able to use tight_layout for Method B through using add_axes and set_position instead of using inset_axes?

    – user3076813
    Nov 27 '18 at 18:31



















  • Both of your methods work perfectly fine for pie charts since you're working with radius. Is there a more general solution that works for any type of graph where radius is irrelevant (e.g., line plots)?

    – user3076813
    Nov 26 '18 at 21:40











  • Sure, just rename radius to something else.

    – ImportanceOfBeingErnest
    Nov 26 '18 at 21:43











  • Sorry. I might be talking about something very obvious that is not very clear to me. I meant radius is a keyword argument for function pie, which determines the size of the pie, but we may not have such a single parameter to set the size for other plot types (like a linear).

    – user3076813
    Nov 26 '18 at 21:53











  • Ok, obviously you cannot use the solution A. For solution B. there is no radius defined inside of pie. Hence you can just ignore it.

    – ImportanceOfBeingErnest
    Nov 26 '18 at 21:54











  • Is it possible to get around the problem of not being able to use tight_layout for Method B through using add_axes and set_position instead of using inset_axes?

    – user3076813
    Nov 27 '18 at 18:31

















Both of your methods work perfectly fine for pie charts since you're working with radius. Is there a more general solution that works for any type of graph where radius is irrelevant (e.g., line plots)?

– user3076813
Nov 26 '18 at 21:40





Both of your methods work perfectly fine for pie charts since you're working with radius. Is there a more general solution that works for any type of graph where radius is irrelevant (e.g., line plots)?

– user3076813
Nov 26 '18 at 21:40













Sure, just rename radius to something else.

– ImportanceOfBeingErnest
Nov 26 '18 at 21:43





Sure, just rename radius to something else.

– ImportanceOfBeingErnest
Nov 26 '18 at 21:43













Sorry. I might be talking about something very obvious that is not very clear to me. I meant radius is a keyword argument for function pie, which determines the size of the pie, but we may not have such a single parameter to set the size for other plot types (like a linear).

– user3076813
Nov 26 '18 at 21:53





Sorry. I might be talking about something very obvious that is not very clear to me. I meant radius is a keyword argument for function pie, which determines the size of the pie, but we may not have such a single parameter to set the size for other plot types (like a linear).

– user3076813
Nov 26 '18 at 21:53













Ok, obviously you cannot use the solution A. For solution B. there is no radius defined inside of pie. Hence you can just ignore it.

– ImportanceOfBeingErnest
Nov 26 '18 at 21:54





Ok, obviously you cannot use the solution A. For solution B. there is no radius defined inside of pie. Hence you can just ignore it.

– ImportanceOfBeingErnest
Nov 26 '18 at 21:54













Is it possible to get around the problem of not being able to use tight_layout for Method B through using add_axes and set_position instead of using inset_axes?

– user3076813
Nov 27 '18 at 18:31





Is it possible to get around the problem of not being able to use tight_layout for Method B through using add_axes and set_position instead of using inset_axes?

– user3076813
Nov 27 '18 at 18:31


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53382914%2fplace-multiple-plots-into-one-big-axis-at-specific-coordinates%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

Npm cannot find a required file even through it is in the searched directory