2017-10-19 191 views
1

我想从matplotlib中的纸张重现图形,如下所示。基本上,每个小区中有一个百分比,和百分比越高,颜色越深单元格的背景:在matplotlib imshow函数中更改像素形状

enter image description here

下面的代码产生类似的东西,但是每个小区是一个正方形像素和我会就像上面的图片一样,它们是平坦的矩形而不是正方形。我如何用matplotlib实现这一点?

import numpy as np 
import matplotlib.pyplot as plt 
import itertools 

table = np.random.uniform(low=0.0, high=1.0, size=(10,5)) 

class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'] 

plt.figure() 
plt.imshow(table, interpolation='nearest', cmap=plt.cm.Greys, vmin=0, vmax=1) 
plt.yticks(np.arange(10), class_names) 

for i,j in itertools.product(range(table.shape[0]), range(table.shape[1])): 
    plt.text(j, i, format(table[i,j], '.2f'), 
      horizontalalignment="center", 
      color="white" if table[i,j] > 0.5 else "black") 

plt.show() 

这里就是上面这段代码产生: enter image description here

我怀疑是改变aspectextentimshow可以帮助我在这里。我不完全理解它是如何工作的,但这里是我试过:

plt.imshow(table, interpolation='nearest', cmap=plt.cm.Greys, vmin=0, vmax=1, aspect='equal', extent=[0,14,10,0])

这将产生以下: enter image description here

我知道我还需要添加的边界细胞,删除刻度标记,并将值更改为百分比而不是小数,我相信我可以自己做到这一点,但如果你想帮助我,那么请随时免费!

+1

也许这个计算器链接[Imshow:程度和纵横](https://stackoverflow.com/问题/ 13384653/imshow-extent-and-aspect)回答你的问题 – Spezi94

+1

@ Spezi94谢谢,我看到了这个答案并尝试了一下,但是我无法确定在aspect和extent被改变后文本的位置是如何工作的。我会更新这个问题来反映这个问题 – timleathart

+1

使用'extent = [0,14,0,10]'给出一个漂亮的数字(至少对我来说)。虽然我也没有想出如何放置文本..... – DavidG

回答

3

imshow呼叫使用aspect="auto"时,您将获得非方形像素:

import numpy as np 
import matplotlib.pyplot as plt 
import itertools 

table = np.random.uniform(low=0.0, high=1.0, size=(10,5)) 

class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'] 

plt.figure() 
plt.imshow(table, interpolation='nearest', cmap=plt.cm.Greys, vmin=0, vmax=1, aspect="auto") 
plt.yticks(np.arange(10), class_names) 

for i,j in itertools.product(range(table.shape[0]), range(table.shape[1])): 
    plt.text(j, i, format(table[i,j], '.2f'), 
      ha="center", va="center", 
      color="white" if table[i,j] > 0.5 else "black") 

plt.show() 

enter image description here

+0

这比我的解决方案简单得多。谢谢! – timleathart

2

经过大量实验后,我想出了程度如何工作以及以后如何影响文本的坐标。我还添加了边框等,并且此代码生成原始样式的相当不错的副本!

import numpy as np 
import matplotlib 
import matplotlib.pyplot as plt 
import itertools 

table = np.random.uniform(low=0.0, high=1.0, size=(10,5)) 

class_names = ['airplane', 'auto', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck'] 

plt.figure() 

plt.imshow(table, interpolation='nearest', cmap=plt.cm.Greys, vmin=0, vmax=1, aspect='equal', extent=[0,14,10,0]) 
plt.yticks(np.arange(10)+0.5, class_names) 
plt.xticks(np.arange(5)*2.8 + 1.4, ['1', '2', '3', '4', '5']) 
ax = plt.axes() 
ax.yaxis.set_ticks_position('none') 
ax.xaxis.set_ticks_position('none') 

matplotlib.rcParams.update({'font.size': 14}) 

ax = plt.gca() 

# Minor ticks 
ax.set_xticks(np.arange(1, 5) * 2.8, minor=True); 
ax.set_yticks(np.arange(1, 10, 1), minor=True); 

# Gridlines based on minor ticks 
ax.grid(which='minor', color='black', linestyle='-', linewidth=1) 

for i,j in itertools.product(range(table.shape[0]), range(table.shape[1])): 
    plt.text(j*2.8+1.5, i+0.6, format(table[i,j], '.2f'), 
      horizontalalignment="center", 
      color="white" if table[i,j] > 0.5 else "black") 

plt.show() 

enter image description here

感谢DavidG和Spezi94谁与他们的评论帮助!