Place multiple plots into one big axis at specific coordinates
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:
python matplotlib subplot
add a comment |
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:
python matplotlib subplot
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
add a comment |
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:
python matplotlib subplot
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:
python matplotlib subplot
python matplotlib subplot
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
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()
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()
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.
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 renameradius
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 noradius
defined inside ofpie
. 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
|
show 4 more comments
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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()
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()
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.
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 renameradius
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 noradius
defined inside ofpie
. 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
|
show 4 more comments
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()
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()
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.
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 renameradius
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 noradius
defined inside ofpie
. 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
|
show 4 more comments
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()
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()
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.
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()
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()
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.
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 renameradius
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 noradius
defined inside ofpie
. 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
|
show 4 more comments
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 renameradius
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 noradius
defined inside ofpie
. 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
|
show 4 more comments
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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