使用 matplotlib.pyplot 添加轴时如何保持分辨率?
How to preserve the resolution when adding axis using matplotlib.pyplot?
如果下面的代码是运行
import matplotlib.pyplot as plt
import numpy as np
a=np.random.random((1000,1000))
plt.imshow(a, cmap='Reds', interpolation='nearest')
plt.savefig('fig.png',bbox_inches='tight')
我得到了下面的图片,所有单元格代表每个随机数。
但是,当如下代码所示添加轴时:
import matplotlib.pyplot as plt
import numpy as np
a=np.random.random((1000,1000))
plt.imshow(a, cmap='Reds', interpolation='nearest')
plt.xlim(0, 10)
plt.xticks(list(range(0, 10)))
plt.ylim(0, 10)
plt.yticks(list(range(0, 10)))
plt.savefig('fig3.png',bbox_inches='tight')
我得到了分辨率较低的图片:
那么如何在不影响分辨率的情况下添加轴刻度呢?如果这与轴标记的字体大小有关,如何自动调整以保持原始分辨率?
对您的问题的应用:
from matplotlib.ticker import FuncFormatter
from matplotlib.pyplot import show
import matplotlib.pyplot as plt
import numpy as np
a=np.random.random((1000,1000))
# create scaled formatters / for Y with Atom prefix
formatterY = FuncFormatter(lambda y, pos: 'Atom {0:g}'.format(y*0.01))
formatterX = FuncFormatter(lambda x, pos: '{0:g}'.format(x*0.01))
# apply formatters
fig, ax = plt.subplots()
ax.yaxis.set_major_formatter(formatterY)
ax.xaxis.set_major_formatter(formatterX)
plt.imshow(a, cmap='Reds', interpolation='nearest')
# create labels
plt.xlabel('nanometer')
plt.ylabel('measure')
plt.xticks(list(range(0, 1001,100)))
plt.yticks(list(range(0, 1001,100)))
plt.show()
来源:
一个可能的解决方案是根据一些函数来格式化刻度标签,如下面来自 matplotlib 页面的示例代码所示。
from matplotlib.ticker import FuncFormatter
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(4)
money = [1.5e5, 2.5e6, 5.5e6, 2.0e7]
def millions(x, pos):
'The two args are the value and tick position'
return '$%1.1fM' % (x * 1e-6)
formatter = FuncFormatter(millions)
fig, ax = plt.subplots()
ax.yaxis.set_major_formatter(formatter)
plt.bar(x, money)
plt.xticks(x, ('Bill', 'Fred', 'Mary', 'Sue'))
plt.show()
this answer 中显示了类似的解决方案,其中
你可以设置一个函数来为你标记轴并缩小它:
ticks = ticker.FuncFormatter(lambda x, pos: '{0:g}'.format(x*scale))
ax.xaxis.set_major_formatter(ticks)
在这里,您需要做 /100
而不是 *scale
对你来说更简单的方法可能是:
ticks = plt.xticks()/100
plt.gca().set_xticklabels(ticks.astype(int))
(adapted from )
您将使用图像的 extent
将其带入新坐标 space。
目前它的范围在 space 之间,介于 0 和 999 之间。这意味着轴限制是 (-0.5, 999.5)
。您可以从函数计算新的范围,例如f = lambda x: x/100.
并将结果设置为图像的新范围。
这将使图像占据 (-0.005, 9.995)
之间的轴范围。现在可以直接设置问题中的刻度(标签)。
import matplotlib.pyplot as plt
import numpy as np
a=np.random.random((1000,1000))
im = plt.imshow(a, cmap='Reds', interpolation='nearest')
f = lambda x: x/100.
(llx,ulx),(lly,uly) = plt.xlim(),plt.ylim()
im.set_extent([f(llx),f(ulx),f(lly),f(uly)])
plt.xticks(list(range(0, 10)))
plt.yticks(list(range(0, 10)))
plt.show()
如果下面的代码是运行
import matplotlib.pyplot as plt
import numpy as np
a=np.random.random((1000,1000))
plt.imshow(a, cmap='Reds', interpolation='nearest')
plt.savefig('fig.png',bbox_inches='tight')
我得到了下面的图片,所有单元格代表每个随机数。
但是,当如下代码所示添加轴时:
import matplotlib.pyplot as plt
import numpy as np
a=np.random.random((1000,1000))
plt.imshow(a, cmap='Reds', interpolation='nearest')
plt.xlim(0, 10)
plt.xticks(list(range(0, 10)))
plt.ylim(0, 10)
plt.yticks(list(range(0, 10)))
plt.savefig('fig3.png',bbox_inches='tight')
我得到了分辨率较低的图片:
那么如何在不影响分辨率的情况下添加轴刻度呢?如果这与轴标记的字体大小有关,如何自动调整以保持原始分辨率?
对您的问题的应用:
from matplotlib.ticker import FuncFormatter
from matplotlib.pyplot import show
import matplotlib.pyplot as plt
import numpy as np
a=np.random.random((1000,1000))
# create scaled formatters / for Y with Atom prefix
formatterY = FuncFormatter(lambda y, pos: 'Atom {0:g}'.format(y*0.01))
formatterX = FuncFormatter(lambda x, pos: '{0:g}'.format(x*0.01))
# apply formatters
fig, ax = plt.subplots()
ax.yaxis.set_major_formatter(formatterY)
ax.xaxis.set_major_formatter(formatterX)
plt.imshow(a, cmap='Reds', interpolation='nearest')
# create labels
plt.xlabel('nanometer')
plt.ylabel('measure')
plt.xticks(list(range(0, 1001,100)))
plt.yticks(list(range(0, 1001,100)))
plt.show()
来源:
一个可能的解决方案是根据一些函数来格式化刻度标签,如下面来自 matplotlib 页面的示例代码所示。
from matplotlib.ticker import FuncFormatter import matplotlib.pyplot as plt import numpy as np x = np.arange(4) money = [1.5e5, 2.5e6, 5.5e6, 2.0e7] def millions(x, pos): 'The two args are the value and tick position' return '$%1.1fM' % (x * 1e-6) formatter = FuncFormatter(millions) fig, ax = plt.subplots() ax.yaxis.set_major_formatter(formatter) plt.bar(x, money) plt.xticks(x, ('Bill', 'Fred', 'Mary', 'Sue')) plt.show()
this answer 中显示了类似的解决方案,其中 你可以设置一个函数来为你标记轴并缩小它:
ticks = ticker.FuncFormatter(lambda x, pos: '{0:g}'.format(x*scale)) ax.xaxis.set_major_formatter(ticks)
在这里,您需要做 /100
而不是 *scale
对你来说更简单的方法可能是:
ticks = plt.xticks()/100 plt.gca().set_xticklabels(ticks.astype(int))
(adapted from )
您将使用图像的 extent
将其带入新坐标 space。
目前它的范围在 space 之间,介于 0 和 999 之间。这意味着轴限制是 (-0.5, 999.5)
。您可以从函数计算新的范围,例如f = lambda x: x/100.
并将结果设置为图像的新范围。
这将使图像占据 (-0.005, 9.995)
之间的轴范围。现在可以直接设置问题中的刻度(标签)。
import matplotlib.pyplot as plt
import numpy as np
a=np.random.random((1000,1000))
im = plt.imshow(a, cmap='Reds', interpolation='nearest')
f = lambda x: x/100.
(llx,ulx),(lly,uly) = plt.xlim(),plt.ylim()
im.set_extent([f(llx),f(ulx),f(lly),f(uly)])
plt.xticks(list(range(0, 10)))
plt.yticks(list(range(0, 10)))
plt.show()