I have a plot with limits -1 to 1. I know the scatter plot doesn't plot with size as a radius, it plots with size as a point.
I need my plot to be scaled correctly with the size of each point, which I have as a radius. Is this possible with modifications to the below code?
fig, ax = plt.subplots(1)
ax.set_title("Post Synaptic Neurons")
sizes = [x.size * 100 for x in post_synaptic_neurons]
offsets = [(x.origin[0],x.origin[1]) for x in post_synaptic_neurons]
print(sizes)
ax.scatter([x.origin[0] for x in post_synaptic_neurons], [x.origin[1] for x in post_synaptic_neurons],
cmap=plt.cm.hsv, s=sizes, alpha=0.5)
ax.set_xlim([-1,1])
ax.set_ylim([-1,1])
ax.set_aspect(1)
plt.tight_layout
If no, can someone explain to me why matplotlib doesn't have a function for plotting a circle with a particular radius on the scale of the plot? I didn't expect this to be an issue, but there must be a good reason behind my difficulties.
As far as I know there is not a high-level way to do this, but you can make it work with an EllipseCollection
. Since your data isn't available, I made some up and wrote this code:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.collections import EllipseCollection
x, y = 1500 * np.random.rand(2, 100)
size = 50 + 10 * np.random.randn(100)
color = np.random.rand(100)
cmap = plt.cm.hsv
fig, ax = plt.subplots(1, 2, figsize=(16, 6),
sharex=True, sharey=True)
ax[0].scatter(x, y, s=size, c=color, cmap=cmap)
offsets = list(zip(x, y))
ax[1].add_collection(EllipseCollection(widths=size, heights=size, angles=0, units='xy',
facecolors=plt.cm.hsv(color),
offsets=offsets, transOffset=ax[1].transData))
ax[1].axis('equal') # set aspect ratio to equal
ax[1].axis([-400, 1800, -200, 1600])
The result is what you hope for; simple scatter plot on the left, scaled plot on the right:
If you scale the plots, say by changing the axis limits to ax[1].axis([200, 1000, 300, 900])
, then the circles on the right plot scale as desired:
You can find more examples of using collections in the matplotlib docs.