[Python]如何使用Matplotlib创建2D直方图


绘制二维直方图时,"三维图"或"二维频率被分配给颜色或密度"。
虽然很容易理解三维图中频率方向的变化,但由于存在隐藏部分,可能难以理解整个分布。
另一方面,当在二维上将频率分配给颜色或浓度时,很难理解频率方向上的细微差别,但是很容易掌握整体分布。

数据

两个二维正态分布用作数据。分布如下。

1
2
3
import numpy as np
x, y = np.vstack((np.random.multivariate_normal([0, 0], [[10.0, 0],[0,20]], 5000)
                 ,np.random.multivariate_normal([0,15], [[10.0, 0],[0, 5]], 5000))).T

hist2d_01.png

二维直方图

2D直方图使用matplotlib的hist2d。
获得直方图的频率作为返回值。
返回值为counts, xedges, yedges, Image

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

fig = plt.figure()
ax = fig.add_subplot(111)

H = ax.hist2d(x,y, bins=40, cmap=cm.jet)
ax.set_title('1st graph')
ax.set_xlabel('x')
ax.set_ylabel('y')
fig.colorbar(H[3],ax=ax)
plt.show()

hist2d_02.png

指定箱数

箱的数量由参数箱如果用标量指定,则仓的数量在垂直和水平方向上都相同。
如果要单独指定它们,请使用示例。
可以指定边缘以及一维直方图。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

fig = plt.figure()
ax = fig.add_subplot(111)

H = ax.hist2d(x,y, bins=[40,10], cmap=cm.jet)
ax.set_title('2nd graph')
ax.set_xlabel('x')
ax.set_ylabel('y')

fig.colorbar(H[3],ax=ax)
plt.show()

hist2d_03.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

fig = plt.figure()
ax = fig.add_subplot(111)

H = ax.hist2d(x,y, bins=[np.linspace(-30,30,61),np.linspace(-30,30,61)], cmap=cm.jet)
ax.set_title('3rd graph')
ax.set_xlabel('x')
ax.set_ylabel('y')

fig.colorbar(H[3],ax=ax)
plt.show()

hist2d_04.png

归一化

如果要标准化直方图,请将标准参数设置为True。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

fig = plt.figure()
ax = fig.add_subplot(111)

H = ax.hist2d(x,y, bins=[np.linspace(-30,30,61),np.linspace(-30,30,61)], normed=True, cmap=cm.jet)
ax.set_title('4th graph')
ax.set_xlabel('x')
ax.set_ylabel('y')

fig.colorbar(H[3],ax=ax)
plt.show()

hist2d_05.png

更改颜色图

要更改颜色贴图,请在参数cmap中将其指定,如示例所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

fig = plt.figure()
ax = fig.add_subplot(111)

H = ax.hist2d(x,y, bins=[np.linspace(-30,30,61),np.linspace(-30,30,61)], normed=True, cmap=cm.gray)
ax.set_title('5th graph')
ax.set_xlabel('x')
ax.set_ylabel('y')
fig.colorbar(H[3],ax=ax)
plt.show()

hist2d_06.png

指定颜色图的范围

有时您需要在比较多个直方图时指定颜色图范围。
在这种情况下,请按照示例使用set_clim。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

fig = plt.figure()
ax = fig.add_subplot(111)

H = ax.hist2d(x,y, bins=[np.linspace(-30,30,61),np.linspace(-30,30,61)], normed=True, cmap=cm.jet)
ax.set_title('6th graph')
ax.set_xlabel('x')
ax.set_ylabel('y')
H[3].set_clim(0,0.05)
fig.colorbar(H[3],ax=ax)
plt.show()

hist2d_07.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

fig = plt.figure()
ax = fig.add_subplot(111)

H = ax.hist2d(x,y, bins=[np.linspace(-30,30,61),np.linspace(-30,30,61)], normed=True, cmap=cm.jet)
ax.set_title('7th graph')
ax.set_xlabel('x')
ax.set_ylabel('y')
H[3].set_clim(0,0.01)
fig.colorbar(H[3],ax=ax)
plt.show()

hist2d_08.png

对数刻度

使用matplotlib.colors.LogNorm()制作直方图对数刻度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
import matplotlib.cm as cm

fig = plt.figure()
ax = fig.add_subplot(111)

H = ax.hist2d(x,y, bins=[np.linspace(-30,30,61),np.linspace(-30,30,61)], norm=matplotlib.colors.LogNorm(), cmap=cm.jet)
ax.set_title('8th graph')
ax.set_xlabel('x')
ax.set_ylabel('y')

fig.colorbar(H[3],ax=ax)
plt.show()

hist2d_09.png

在直方图

上方叠加轮廓线(轮廓)

等高线是用等高线写的。
此时,请注意以下几点
1.指定范围的最大值和最小值,以使水平和垂直位置与直方图相匹配。
2.计算转置,因为它在垂直方向上包含x轴数据,在水平方向上包含y轴数据。
3.使用LogNorm以对数显示。您不必拥有它,但是没有它您几乎看不到它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors
import matplotlib.cm as cm

fig = plt.figure()
ax = fig.add_subplot(111)

counts, xedges, yedges, Image= ax.hist2d(x,y, bins=[np.linspace(-30,30,61),np.linspace(-30,30,61)], norm=matplotlib.colors.LogNorm(), cmap=cm.jet)
ax.contour(counts.transpose(),extent=[xedges.min(),xedges.max(),yedges.min(),yedges.max()])
ax.set_title('8th graph')
ax.set_xlabel('x')
ax.set_ylabel('y')
fig.colorbar(Image,ax=ax)
plt.show()

hist2d_10.png

使直方图容器形状为六角形

当您想要使瓶子的形状为六角形时。

1
2
3
4
5
6
7
8
9
10
11
12
13
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

fig = plt.figure()
ax = fig.add_subplot(111)

H = ax.hexbin(x,y, gridsize=20, extent=[-30, 30, -30, 30], cmap=cm.jet)
ax.set_title('8th graph')
ax.set_xlabel('x')
ax.set_ylabel('y')
fig.colorbar(H,ax=ax)
plt.show()

hist2d_11.png

平滑直方图(内核密度估计)

直方图是块状的,尤其是在bin间隔较宽时。
有一种内核密度估计作为将其平滑连接的方法。
这是用于根据随机变量的采样分布来估计概率密度函数。

内核密度估计包含在scipy和scikit-learn中。
scipy内核密度估计指定通过标准偏差归一化的带宽。
结果,即使数据分布改变,也可以平滑地估计。
因此,当参数bw_method = 1.0时,value.std(ddof = 1)用作带宽。 (值就是数据)
在计算具有自由度增量的标准偏差时,ddof除以N-ddof。

kernel = gaussian_kde(value)中,内核是gaussian_kde对象,因此,如果您真的想获取值,请
传递x和y坐标的位置,如kernel(positions)

实际上,实际上是使用mgrid创建了一个网格,使用ravel将x和y分别制成一维,并使用vstack附加它们,然后将其传递给内核。

由于

kernel(positions)返回的值是一维的,因此通过整形使其成为二维。

最后,它显示为带有轮廓线f的图形。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde
import matplotlib.cm as cm

xx,yy = np.mgrid[-30:30:1,-30:30:1]
positions = np.vstack([xx.ravel(),yy.ravel()])

value = np.vstack([x,y])

kernel = gaussian_kde(value)

f = np.reshape(kernel(positions).T, xx.shape)

fig = plt.figure()
ax = fig.add_subplot(111)

ax.contourf(xx,yy,f, cmap=cm.jet)
ax.set_title('11th graph')
ax.set_xlabel('x')
ax.set_ylabel('y')
plt.show()

hist2d_12.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde
import matplotlib.cm as cm

xx,yy = np.mgrid[-30:30:1,-30:30:1]
positions = np.vstack([xx.ravel(),yy.ravel()])

value = np.vstack([x,y])

kernel = gaussian_kde(value, bw_method=0.5)

f = np.reshape(kernel(positions).T, xx.shape)

fig = plt.figure()
ax = fig.add_subplot(111)

ax.contourf(xx,yy,f, cmap=cm.jet)
ax.set_title('12th graph')
ax.set_xlabel('x')
ax.set_ylabel('y')
plt.show()

hist2d_13.png

带有numpy直方图

您可以使用

numpy中的histogram2d制作直方图。
在这种情况下,可以获得x和y的频率以及边缘,因此您需要自己绘制图形。
在这里,imshow用于显示。
此时,类似于matplotlib中的hist2d,直方图数据包含在垂直方向上的x轴方向上的数据和在水平方向上的y轴方向上的数据。
它会进行转置并将起点设置在左下方。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

fig = plt.figure()
ax = fig.add_subplot(111)

H = np.histogram2d(x,y, bins=[np.linspace(-30,30,61),np.linspace(-30,30,61)])
im = ax.imshow(H[0].T, interpolation='nearest', origin='lower', extent=[-30,30,-30,30], cmap=cm.jet)
ax.set_title('13st graph')
ax.set_xlabel('x')
ax.set_ylabel('y')
fig.colorbar(im, ax=ax)
plt.show()

hist2d_14.png