a1 = np.random.randint(1,10,size=(10,10))
a2 = np.random.randint(1,13,size=(10,10))
a3 = np.random.randint(1,16,size=(10,10))
fig = plt.figure(figsize = (22,6))
norm = matplotlib.colors.Normalize(vmin=0, vmax=15)
plt.subplot(1,3,1)
h1 = plt.contourf(a1,cmap = plt.cm.coolwarm,norm = norm)
c1 = plt.colorbar(h1)
plt.subplot(1,3,2)
h2 = plt.contourf(a2,cmap = plt.cm.coolwarm,norm = norm)
c2 = plt.colorbar(h2)
plt.subplot(1,3,3)
h3 = plt.contourf(a3,cmap = plt.cm.coolwarm,norm = norm)
c3 = plt.colorbar(h3)
plt.show()

如上图,可以实现相同数值大小对应相同的颜色;
但是这样还是不太好看。最好是能够 每个子图的 colorbar的范围都一样(即从0-15);
那有同学想,是否可以只显示最后一个子图的colorbar,作为全局colorbar呢;这个当然也是可以的。
但是会带来一个问题,由于每个子图的大小(无论是否包含colorbar)是一样的,会使得图形大小看起来不一样,很不美观;
a1 = np.random.randint(1,10,size=(10,10))
a2 = np.random.randint(1,13,size=(10,10))
a3 = np.random.randint(1,16,size=(10,10))
fig = plt.figure(figsize = (22,6))
levels = np.arange(0,17,2)
plt.subplot(1,3,1)
h1 = plt.contourf(a1,cmap = plt.cm.coolwarm,levels = levels)
c1 = plt.colorbar(h1)
plt.subplot(1,3,2)
h2 = plt.contourf(a2,cmap = plt.cm.coolwarm,levels = levels)
c2 = plt.colorbar(h2)
plt.subplot(1,3,
3)
h3 = plt.contourf(a3,cmap = plt.cm.coolwarm,levels = levels)
c3 = plt.colorbar(h3)
plt.show()
上面虽然设置了 norm,但是使用plt.contourf还是达不到我们的要求。链接3 给了我们一个示例,使用plt.imshow() + norm可以解决这个问题。按照他的思路,我们重复上面的试验。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
# matplotlib.rcParams['xtick.direction'] = 'out'
# matplotlib.rcParams['ytick.direction'] = 'out'
a1 = np.random.randint(1,10,size=(10,10))
a2 = np.random.randint(1,13,size=(10,10))
a3 = np.random.randint(1,16,size=(10,10))
fig = plt.figure(figsize = (22,6),dpi=72, facecolor="white")
#将横纵坐标都映射到(0,1)的范围内
extent=(0,1,0,1)
vmin=0
vmax=15
#将颜色映射到 vmin~vmax 之间
norm = matplotlib.colors.Normalize(vmin=0, vmax=15)
ax1 = plt.subplot(1,3,1)
ax1.cla()
h1 = plt.imshow(a1,extent = extent,origin='lower',cmap = plt.cm.coolwarm,norm = norm)
c1 = plt.colorbar(h1)
plt.subplot(1,3,2)
h2 = plt.imshow(a2,extent = extent,origin='lower',cmap = plt.cm.coolwarm,norm = norm)
c2 = plt.colorbar(h2)
plt.subplot(1,3,3)
h3 = plt.imshow(a3,extent = extent,origin='lower',cmap = plt.cm.coolwarm,norm = norm)
c3 = plt.colorbar(h3)
font = {'family' : 'serif',
'color' : 'darkred',
'weight' : 'normal',
'size' : 16,
c3.set_label('$T_B(K)$',fontdict=font)
c3.set_ticks(np.arange(vmin,vmax,2))
c3.set_ticklabels(np.arange(vmin,vmax,2))
plt.show()
如上图,虽然使用plt.imshow可以解决这个问题,但是用带来了一些新问题:
- 在画子图的时候,colorbar的长度和子图的长度不一致;在单独画一个图的时候,并不存在这样的问题
- plt.imshow()是逐像素画图的,相比plt.contourf,分辨率很低,并不适合科研上的等值线作图。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
a1 = np.random.randint(1,10,size=(10,10))
a2 = np.random.randint(1,13,size=(10,10))
a3 = np.random.randint(1,16,size=(10,10))
fig = plt.figure(figsize = (22,6))
norm = matplotlib.colors.Normalize(vmin=0, vmax=15)
plt.subplot(1,3,1)
h1 = plt.contourf(a1,cmap = plt.cm.coolwarm,norm = norm)
plt.subplot(1,3,2)
h2 = plt.contourf(a2,cmap = plt.cm.coolwarm,norm = norm)
plt.subplot(1,3,3)
h3 = plt.contourf(a3,cmap = plt.cm.coolwarm,norm = norm)
fig.subplots_adjust(right=0.9)
l = 0.92
b = 0.12
w = 0.015
h = 1 - 2*b
rect = [l,b,w,h]
cbar_ax = fig.add_axes(rect)
cb = plt.colorbar(h3, cax=cbar_ax)
cb.ax.tick_params(labelsize=16)
font = {'family' : 'serif',
'color' : 'black',
'weight' : 'normal',
'size' : 16,
cb.set_label('T' ,fontdict=font)
plt.show()

如上,是不是很漂亮了。后续适当做一些 坐标、字体等的基本设置,就完成了一张科研图的绘制!
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
a1 = np.random.randint(1,10,size=(10,10))
a2 = np.random.randint(1,13,size=(10,10))
a3 = np.random.randint(1,16,size=(10,10))
fig = plt.figure(figsize = (22,6))
norm = matplotlib.colors.Normalize(vmin=0, vmax=15)
plt.subplot(1,3,1)
h1 = plt.contourf(a1,cmap = plt.cm.coolwarm,norm = norm)
plt.subplot(1,3,2)
h2 = plt.contourf(a2,cmap = plt.cm.coolwarm,norm = norm)
plt.subplot(1,3,3)
h3 = plt.contourf(a3,cmap = plt.cm.coolwarm,norm = norm)
fig.subplots_adjust(right=0.9)
l = 0.92
b = 0.12
w = 0.015
h = 1 - 2*b
rect = [l,b,w,h]
cbar_ax = fig.add_axes(rect)
cb = plt.colorbar(h3, cax=cbar_ax)
cb.ax.tick_params(labelsize=16)
font = {'family' : 'serif',
'color' : 'black',
'weight' : 'normal',
'size' : 16,
cb.set_label('T' ,fontdict=font)
plt.show()

如上,是不是很漂亮了。后续适当做一些 坐标、字体等的基本设置,就完成了一张科研图的绘制!
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
fig, axes = plt.subplots(nrows=2, ncols=2,figsize = (12,10))
a_list = [5,10,15,20]
vmin = 0
vmax = 20
norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)
for a,ax in zip(a_list,axes.flat):
data = np.random.randint(0,a,size = (20,20))
im = ax.contourf(data,norm = norm)
fig.subplots_adjust(right=0.8)
l = 0.85
b = 0.12
w = 0.05
h = 1 - 2*b
rect = [l,b,w,h]
cbar_ax = fig.add_axes(rect)
cb = fig.colorbar(im, cax = cbar_ax)
cb.ax.tick_params(labelsize=16)
font = {'family' : 'serif',
'color' : 'black',
'weight' : 'normal',
'size' : 16,
cb.set_label('T' ,fontdict=font)
plt.show()
上述两种方式都存在一个潜在的问题。
在添加colorbar的时,是使用最后一个子图的所在的数值范围。我们来看几种情况。
最后一张子图的数据范围决定了colorbar上显示的刻度的范围。
norm范围决定了colorbar颜色变化范围。
为了保证colorbar能覆盖所有子图的范围,应该使得 norm范围与设置colorbar时对应的子图im 的数值范围一致,并且所有子图的数值范围应该都在norm范围之内。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bI7GRXmn-1582701105492)(matplotlib 合理设置colorbar和子图的对应关系.assets/image-20200226135804785.png)]
因此有一个蠢办法:
-
即另外建一个fig2 , 这个fig2对应的数据范围包括fig1的数据范围。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
fig1, axes = plt.subplots(nrows=2, ncols=2,figsize = (10,8))
a_list = [5,10,20,15]
vmin = 0
vmax = 20
norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)
for a,ax in zip(a_list,axes.flat):
data = np.random.randint(0,a,size = (20,20))
im = ax.contourf(data,norm = norm)
fig1.subplots_adjust(right=0.8)
l = 0.85
b = 0.12
w = 0.05
h = 1 - 2*b
rect = [l,b,w,h]
cbar_ax = fig1.add_axes(rect)
fig2 = plt.figure(figsize = (18,6))
all_data = np.random.randint(vmin,vmax,size = (20,20))
h4 = plt.contourf(all_data,norm = norm)
cb = fig1.colorbar(h4, cax = cbar_ax)
cb.ax.tick_params(labelsize=16)
font = {'family' : 'serif',
'color' : 'black',
'weight' : 'normal',
'size' : 16,
cb.set_label('T' ,fontdict=font)
plt.show()
对比上述情况2的图片,情况有所改善,但是吊了一个尾巴。
import numpy as np
import matplotlib.pyplot as plt
a_list = [5,10,20,15]
vmin = 0
vmax = 20
norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)
fig, axes = plt.subplots(nrows=2, ncols=2)
for a,ax in zip(a_list,axes.flat):
data = np.random.randint(0,a,size = (20,20))
im = ax.imshow(data , vmin = vmin, vmax = vmax )
fig.colorbar(im, ax=axes.ravel().tolist())
plt.show()
使用这个方法可以解决上述情况2的问题,不需要吊个尾巴啦!
至于使用plt.imshow 和 plt.contourf,看各自喜好!另外,建议多看看官网例子。
[1] 解决python画图中colorbar设置刻度和标签字体大小
[2] 使用matplotlib的示例:调整字体-设置刻度、坐标、colormap和colorbar等
[3] matplotlib官网例子
🌈颜色,不仅是视觉的享受,更是数据可视化的灵魂!在Matplotlib的世界里,plt.colorbar就像一根魔法棒,为你的图表增添色彩和深度。🎨
🌟从入门到精通,本文带你探索plt.colorbar的奥秘!无论是简单应用还是高级定制,你都能在这里找到答案。🛠️
🔍详解plt.colorbar的关键参数,如extend、orientation和ticks,让你的颜色条更加精准、生动!🌈
cm1 = plt.cm.get_cmap('RdYlBu')
cm2 = plt.cm.get_cmap('RdYlBu_r') # RdYlBu_r末尾加r表示颜色取反
x=np.random.randn(50)
y=np.random.randn(50)
plt.figure()
转载于:Matplotlib 系列:colorbar 的设置
该文为我很及时的解决了我的烦恼,再次向作者致意~
作者一直在持续更新python系列,请支持原作者,文章来源:炸鸡人博客
0. 前言
承接 Matplotlib 系列:colormap 的设置 一文,这次介绍 colorbar。所谓 colorbar 即主图旁一个长条状的小图,能够辅助表示主图中 colormap 的颜色组成和颜色与数值的对应关系。本文将会依次介绍 colorbar 的基本用法、如何设置刻度,以及怎么为组图添加 colorbar。
几种图像读取方式总结
import matplotlib.image as img :img.imread()
import PIL.Image as Img :Img.open()
import tensorflow as tf :tf.read_file()
import cv2:cv2.imread()
需要注意:一、对于低版本的tf,需要将图片经过tf.Session()执行
二、cv2读取文件中不能有中文字符
三、cv2读取三通道和单通道的不同
四、cv2的取的图片文件使用cv.imshow
python很火,因为有各种库的支持,所以功能格外强大。在可视化方面,目前用得较多的是matplotlib.
在基于matplotlib.pyplot画带色标(colorbar)的图时候,往往为了美观和科研用途,需要对colorbar的Ticks(刻度) ,标签(label)和fonddict(字体进行设置)。但是很多初学者都苦于这些东西的设置,因为太麻烦了(别问我怎么知道的)。以下将介绍...
通过调整width参数可以控制颜色条的宽度,通过height参数可以控制颜色条的高度。在示例中,我将宽度设置为图形宽度的5%(“5%”),高度设置为图形高度的100%(“100%”),你可以根据需要自行调整这些值。colorbar()函数是用于在图形中添加颜色条的方法之一,它可以接受一些参数以控制颜色条的外观和布局。**问:**上面这个脚本中我试了好像没有吧colorbar的大小进行调节,只是调节了字体等,能不能把colorbar的主体大小也进行调节。通过以上方法,你可以自定义颜色条的大小来满足你的需求。