scatter plot with single pixel marker in matplotlib

怎甘沉沦 提交于 2019-12-01 06:07:11

The problem

I fear that the bugfix discussed at matplotlib git repository that you're citing is only valid for plt.plot() and not for plt.scatter()

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(4,2))
ax = fig.add_subplot(121)
ax2 = fig.add_subplot(122, sharex=ax, sharey=ax)
ax.plot([1, 2],[0.4,0.4],color='black',marker=',',lw=0, linestyle="")
ax.set_title("ax.plot")
ax2.scatter([1,2],[0.4,0.4],color='black',marker=',',lw=0, s=1)
ax2.set_title("ax.scatter")
ax.set_xlim(0,8)
ax.set_ylim(0,1)
fig.tight_layout()
print fig.dpi #prints 80 in my case
fig.savefig('plot.png', dpi=fig.dpi)

The solution: Setting the markersize

The solution is to use a usual "o" or "s" marker, but set the markersize to be exactly one pixel. Since the markersize is given in points, one would need to use the figure dpi to calculate the size of one pixel in points. This is 72./fig.dpi.

  • For aplot`, the markersize is directly

    ax.plot(..., marker="o", ms=72./fig.dpi)
    
  • For a scatter the markersize is given through the s argument, which is in square points,

    ax.scatter(..., marker='o', s=(72./fig.dpi)**2)
    

Complete example:

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(4,2))
ax = fig.add_subplot(121)
ax2 = fig.add_subplot(122, sharex=ax, sharey=ax)
ax.plot([1, 2],[0.4,0.4], marker='o',ms=72./fig.dpi, mew=0, 
        color='black', linestyle="", lw=0)
ax.set_title("ax.plot")
ax2.scatter([1,2],[0.4,0.4],color='black', marker='o', lw=0, s=(72./fig.dpi)**2)
ax2.set_title("ax.scatter")
ax.set_xlim(0,8)
ax.set_ylim(0,1)
fig.tight_layout()
fig.savefig('plot.png', dpi=fig.dpi)

For anyone still trying to figure this out, the solution I found was to specify the s argument in plt.scatter.

The s argument refers to the area of the point you are plotting.

It doesn't seem to be quite perfect, since s=1 seems to cover about 4 pixels of my screen, but this definitely makes them smaller than anything else I've been able to find.

https://matplotlib.org/devdocs/api/_as_gen/matplotlib.pyplot.scatter.html

s : scalar or array_like, shape (n, ), optional
size in points^2. Default is rcParams['lines.markersize'] ** 2.

Set the plt.scatter() parameter to linewidths=0 and figure out the right value for the parameter s.

Source: https://stackoverflow.com/a/45803960/4063622

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!