1

For some reason when I use a zorder with my scatter plot the edges of the points overlap the axis. I tried some of the solutions from [here] (matplotlib axis tick labels covered by scatterplot (using spines)) but they didn't work for me. Is there a way from preventing this from happening?

I understand I could also add an ax.axvline() at my boundaries but that would be an annoying workaround for lots of plots.

xval = np.array([0,0,0,3,3,3,0,2,3,0])
yval = np.array([0,2,3,5,1,0,1,0,4,5])
zval = yval**2-4

fig = plt.figure(figsize=(6,6))

ax = plt.subplot(111)

ax.scatter(xval,yval,cmap=plt.cm.rainbow,c=zval,s=550,zorder=20)

ax.set_ylim(0,5)
ax.set_xlim(0,3)


#These don't work
ax.tick_params(labelcolor='k', zorder=100)
ax.tick_params(direction='out', length=4, color='k', zorder=100)

#This will work but I don't want to have to do this for the plot edges every time
ax.axvline(0,c='k',zorder=100)


plt.show()

enter image description here

TOPP1111
  • 155
  • 1
  • 9

3 Answers3

2

For me the solution you linked to works; that is, setting the z-order of the scatter plot to a negative number. E.g.

xval = np.array([0,0,0,3,3,3,0,2,3,0])
yval = np.array([0,2,3,5,1,0,1,0,4,5])
zval = yval**2-4

fig = plt.figure(figsize=(6,6))

ax = plt.subplot(111)

ax.scatter(xval,yval,cmap=plt.cm.rainbow,c=zval,s=550,zorder=-1)

ax.set_ylim(0,5)
ax.set_xlim(0,3)

plt.show()

Test plot with axes sitting on top of scatter points]1

LABarnard
  • 290
  • 2
  • 9
  • Thanks for the suggestion. This is an example of another case which has lots of plot components so I need to have a positive `zorder` on the scatter plot. Otherwise I would have to specify greater negative numbers for everything else. – TOPP1111 Aug 13 '19 at 15:28
  • Ah OK. Have you tried setting the axes zorder e.g. `ax.set_zorder(99)`. This seems to work for me, but only whilst the zorder of the scatter plot is < 4. For some reason I don't understand, when the zorder of the scatter >= 4, the scatter points lie on top of the axes, seemingly irrespective of the axes own zorder. – LABarnard Aug 13 '19 at 16:16
1

This works for me

import numpy as np
import matplotlib.pyplot as plt
xval = np.array([0,0,0,3,3,3,0,2,3,0])
yval = np.array([0,2,3,5,1,0,1,0,4,5])
zval = yval**2-4

fig = plt.figure(figsize=(6,6))

ax = plt.subplot(111)

ax.scatter(xval,yval,cmap=plt.cm.rainbow,c=zval,s=550,zorder=20)

ax.set_ylim(-1,6)
ax.set_xlim(-1,4)


#These don't work
ax.tick_params(labelcolor='k', zorder=100)
ax.tick_params(direction='out', length=4, color='k', zorder=100)

#This will work but I don't want to have to do this for the plot edges every time
ax.axvline(0,c='k',zorder=100)


plt.show()

Your circle sizes are big enough that they go beyond the axis scope. So we simply change the ylim and xlim

Changed

ax.set_ylim(0,5)
ax.set_xlim(0,3)

to

ax.set_ylim(-1,6)
ax.set_xlim(-1,4)

Also, zorder doesn't play a role in pushing the points to edges.

enter image description here

Pirate X
  • 3,023
  • 5
  • 33
  • 60
  • Thanks for the suggestion but this is an idealized case for what I am doing and I want to keep the limits. My data has values near zero which represents the surface and below that there isn't anything. I don't care too much about but that data but I still need to show its there. – TOPP1111 Aug 13 '19 at 15:32
1

You can fix the overlap using the following code with a large number for the zorder. This will work on both the x- and y-axis.

for k,spine in ax.spines.items():
    spine.set_zorder(1000)
BenT
  • 3,172
  • 3
  • 18
  • 38