0

I can create a scatter plot as follows:

fig, ax = plt.subplots()
x1 = [1, 1, 2]
y1 = [1, 2, 1]
x2 = [2]
y2 = [2]
ax.scatter(x1, y1, color="red", s=500)
ax.scatter(x2, y2, color="blue", s=500)

which gives

enter image description here

What I would like is something like the following (apologies for poor paint work):

enter image description here

I am plotting data that is all integer values, so they're all on a grid. I would like to be able to control the size of the scatter marker so that I could have white space around the points, or I could make the points large enough such that there would be no white space around them (as I have done in the above paint image).

Note - ideally the solution will be in pure matplotlib, using the OOP interface as they suggest in the documentation.

baxx
  • 3,956
  • 6
  • 37
  • 75
  • A confusion can be that the size of the dots is expressed in 'display coordinates' while the spacing between the dots is expressed in 'data coordinates'. So their relation changes everytime the limits of the x or the y axis are changed (e.g. adding more points), or when the plot is made larger. [This tutorial](https://matplotlib.org/3.2.1/tutorials/advanced/transforms_tutorial.html) gives some additional explanations. – JohanC May 02 '20 at 01:00
  • Check https://stackoverflow.com/questions/48172928/scale-matplotlib-pyplot-axes-scatter-markersize-by-x-scale – ImportanceOfBeingErnest May 04 '20 at 08:56

1 Answers1

2
import matplotlib.pyplot as plt
import matplotlib as mpl

# X and Y coordinates for red circles
red_xs = [1,2,3,4,1,2,3,4,1,2,1,2]
red_ys = [1,1,1,1,2,2,2,2,3,3,4,4]

# X and Y coordinates for blue circles
blu_xs = [3,4,3,4]
blu_ys = [3,3,4,4]

# Plot with a small markersize
markersize = 5
fig, ax = plt.subplots(figsize=(3,3))
ax.plot(red_xs, red_ys, marker="o", color="r", linestyle="", markersize=markersize)
ax.plot(blu_xs, blu_ys, marker="o", color="b", linestyle="", markersize=markersize)
plt.show()

smallmarkers

# Plot with a large markersize
markersize = 50
fig, ax = plt.subplots(figsize=(3,3))
ax.plot(red_xs, red_ys, marker="o", color="r", linestyle="", markersize=markersize)
ax.plot(blu_xs, blu_ys, marker="o", color="b", linestyle="", markersize=markersize)
plt.show()

enter image description here

# Plot with using patches and radius
r = 0.5
fig, ax = plt.subplots(figsize=(3,3))
for x, y in zip(red_xs, red_ys):
    ax.add_patch(mpl.patches.Circle((x,y), radius=r, color="r"))
for x, y in zip(blu_xs, blu_ys):
    ax.add_patch(mpl.patches.Circle((x,y), radius=r, color="b"))
ax.autoscale()
plt.show()

enter image description here

  • thanks - how can you set the size such that the points are large enough so have no whitespace between them, and there is no overlap between points. – baxx May 02 '20 at 13:34
  • @baxx See the updated solution. I attempted to use as little of the object oriented interface as possible, per your request in the original question. – jpvantassel May 03 '20 at 02:33
  • Thank you - but In my original question it says that I *do want* to use the OOP interface, not that I don't. – baxx May 03 '20 at 12:47
  • the patches solution looks nice though, that seems to be the best approach – baxx May 03 '20 at 16:53