之前写过一些 ChatGPT 的使用体验,确实很好,省了很多事,用起来也方便。
> 代码看不懂?不会优化?ChatGPT 来帮你!
> 偷个懒,用ChatGPT 帮我写段生物信息代码
> 1 分钟看 ChatGPT 问答
但 ChatGPT 要想接入还是比较麻烦,有些事情国内模型也可以处理的很好。
不是 ChatGPT 用不起,而是文心一言更有性价比。
写着神经网络计算代码,对矩阵计算想整个清晰的展示方式,就想着用 Python 绘制下矩阵运算图。先偷懒一下,看看有没有人分享过代码?
于是直接百度搜索“如何用 python 绘制矩阵相乘”, 绘制这个单词不太突出,被理解为如何计算矩阵相乘,百度启动文心一言,开始了代码输出:
现在百度很好,一言不合就出代码,那我们就进入问心一言“接着问”。
1. 继续发问:python绘制矩阵相乘
获得答案:
要使用Python绘制两个矩阵的相乘结果,可以按照以下步骤进行操作。
首先,需要导入NumPy库来处理数组运算。然后定义两个输入矩阵A和B,并计算它们的相乘结果C。最后,将结果打印或保存为图像文件。
以下是示例代码:
import numpy as npfrom matplotlib import pyplot as plt# 定义输入矩阵 A 和 BA = [[1, 2], [3, 4]]
B = [[5, 6], [7, 8]]# 计算矩阵相乘结果 CC = np.dot(np.array(A), np.array(B))
print("矩阵相乘结果:\n", C)# 绘制矩阵相乘结果图像plt.imshow(C)
plt.colorbar()
plt.title('Matrix Multiplication')
plt.xlabel('Columns')
plt.ylabel('Rows')# plt.savefig('matrix_multiply.png', dpi=300) # 保存为图片文件plt.show()
这段代码会输出矩阵相乘的结果,并生成一张显示相乘结果的图像文件”matrix_multiply.png”。
输出很详细,不过沟通存在问题,文心一言给出的代码是绘制结果矩阵,出来一张如下的热图。
2. 调整问法继续发问:python 中绘制一幅图展示这段代码的含义 “C = np.dot(np.array(A), np.array(B)”
获得答案:
在Python中,你可以使用matplotlib库来绘制一幅图,以可视化矩阵A和B相乘的过程。但是,由于矩阵乘法本身是一个数值运算,而不是一个可以直接可视化的几何过程,我们通常通过展示输入矩阵和输出矩阵来间接地表示这个过程。
以下是一个简单的例子,展示了如何使用matplotlib绘制矩阵A、B以及它们的乘积C:
import numpy as npimport matplotlib.pyplot as plt# 定义输入矩阵 A 和 BA = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])# 计算矩阵相乘结果 CC = np.dot(A, B)# 绘制矩阵 Aplt.subplot(1, 3, 1)
plt.title('Matrix A')
plt.imshow(A, cmap='gray')# 绘制矩阵 Bplt.subplot(1, 3, 2)
plt.title('Matrix B')
plt.imshow(B, cmap='gray')# 绘制矩阵 Cplt.subplot(1, 3, 3)
plt.title('Matrix C (Result of A x B)')
plt.imshow(C, cmap='gray')# 添加颜色条plt.colorbar()# 展示图形plt.tight_layout()
plt.show()
在这个例子中,imshow函数用于显示矩阵,每个矩阵都被视为一个图像,其中每个元素的值对应于图像上的一个像素的亮度。cmap=’gray’参数指定使用灰度颜色映射,这样矩阵中的数值就可以映射到不同的灰度级别上。
subplot函数用于在单个窗口中创建多个子图。参数1, 3, i表示创建一个1行3列的布局,并且当前正在绘制第i个子图(i为1, 2, 3)。
title函数用于给每个子图添加标题,以表明它显示的是哪个矩阵。
最后,plt.show()命令用于显示整个图形窗口。
请注意,这个可视化方法主要是为了展示矩阵的结构和它们在相乘之前的形状,而不是直接展示相乘的过程。矩阵相乘的过程在数值上是通过对应元素相乘并求和来完成的,这个过程在图像上不易直接表达。
运行代码,输出结果,有这个意思了,3 个矩阵都出来了。但是不太好看,继续发稳修改。
3. 继续发问:隐藏坐标轴和图例
获得答案:
如果你想要隐藏坐标轴和图例,你可以在matplotlib的pyplot模块中设置相应的属性。以下是一个例子,展示了如何绘制两个矩阵相乘的结果,并隐藏坐标轴和图例:
import numpy as npimport matplotlib.pyplot as plt# 定义输入矩阵 A 和 BA = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])# 计算矩阵相乘结果 CC = np.dot(A, B)# 绘制矩阵相乘结果图像plt.imshow(C, cmap='gray')# 隐藏坐标轴plt.axis('off')# 不显示图例plt.gca().legend_ = None# 设置标题plt.title('Matrix Multiplication Result')# 展示图形,但不显示坐标轴和图例plt.show()
在这个例子中,plt.axis(‘off’)用于关闭坐标轴,而plt.gca().legend_ = None用于隐藏图例。cmap=’gray’指定了使用灰度颜色映射来显示矩阵中的数值。
现在,当你运行这段代码时,它会显示一个只包含矩阵相乘结果、没有坐标轴和图例的图像。
这里不知道是问法的问题,还是文心一言没有考虑上下文,给出了一个新的例子,来隐藏坐标轴和图例,需要我们自己把这个代码糅合到上面的程序中。
当然也可以尝试换个问法,这里我得到了提示,就没再问,自己整合了下代码。
import numpy as npimport matplotlib.pyplot as plt# 定义输入矩阵 A 和 BA = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])# 计算矩阵相乘结果 CC = np.dot(A, B)# 绘制矩阵 Aplt.subplot(1, 3, 1)
plt.title('Matrix A')
plt.imshow(A, cmap='gray')
plt.axis('off')# 绘制矩阵 Bplt.subplot(1, 3, 2)
plt.title('Matrix B')
plt.imshow(B, cmap='gray')
plt.axis('off')# 绘制矩阵 Cplt.subplot(1, 3, 3)
plt.title('Matrix C (Result of A x B)')
plt.imshow(C, cmap='gray')
plt.axis('off')# 添加颜色条#plt.colorbar()# 展示图形plt.tight_layout()
plt.show()
获得输出,坐标轴和图例都去掉了
4. 继续发问:每个矩阵方框背景为白色,填充矩阵的值,隐藏坐标轴的刻度和标记
获得答案:
要在matplotlib中设置矩阵方框背景为白色,填充矩阵的值,并隐藏坐标轴的刻度和标记,你可以使用以下代码:
import numpy as npimport matplotlib.pyplot as plt# 定义输入矩阵 A 和 BA = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])# 计算矩阵相乘结果 CC = np.dot(A, B)# 绘制矩阵 Aplt.subplot(1, 3, 1)
plt.axis('off') # 隐藏坐标轴plt.imshow(A, cmap='gray', interpolation='nearest', vmin=0, vmax=np.max(np.abs(A)))
plt.title('Matrix A')# 绘制矩阵 Bplt.subplot(1, 3, 2)
plt.axis('off') # 隐藏坐标轴plt.imshow(B, cmap='gray', interpolation='nearest', vmin=0, vmax=np.max(np.abs(B)))
plt.title('Matrix B')# 绘制矩阵 Cplt.subplot(1, 3, 3)
plt.axis('off') # 隐藏坐标轴plt.imshow(C, cmap='gray', interpolation='nearest', vmin=0, vmax=np.max(np.abs(C)))
plt.title('Matrix C (Result of A x B)')# 添加颜色条plt.subplots_adjust(wspace=0.2, hspace=0.5) # 调整子图之间的间距plt.colorbar(plt.cm.ScalarMappable(cmap='gray'), ax=plt.gca(), shrink=0.5)# 展示图形plt.show()
在这个代码中,plt.axis(‘off’)用于隐藏坐标轴。cmap=’gray’设置了颜色映射为灰度。interpolation=’nearest’指定了图像插值方法为最近邻插值,这样可以保留矩阵的整数性质。vmin和vmax参数设置了颜色映射的最小值和最大值,以确保矩阵中的所有值都在颜色映射的范围内。
plt.subplots_adjust用于调整子图之间的间距,plt.colorbar用于添加颜色条,并且设置shrink参数以调整颜色条的大小。
运行这段代码将生成一幅包含三个子图的图像,每个子图分别展示矩阵A、B和C。每个矩阵的背景色为白色,矩阵值被填充在相应的位置上,坐标轴的刻度和标记都被隐藏了。
这次提问囊括了上下文概念,回复的结果里面,也把前几次的提问整合了起来。
但是,可能一下给的任务太多,并没有达到目的。输出的结果根上一次一样。
5. 任务拆开继续发问: imshow 的每个格子里填写数字
获得答案:
要在imshow中每个格子里填写数字,你可以使用text函数在每个单元格的中心添加文本。由于imshow通常用于显示图像数据,其中每个像素对应一个颜色,因此你需要首先确定你想要如何格式化这些数字(例如,整数、浮点数、百分比等)。
下面是一个例子,展示了如何在imshow的每个格子里填写数字,并且设置背景色为白色:
import numpy as npimport matplotlib.pyplot as plt# 定义输入矩阵 A 和 BA = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])# 计算矩阵相乘结果 CC = np.dot(A, B)# 设置图像的背景色为白色fig, ax = plt.subplots()
ax.imshow(C, cmap='gray', interpolation='nearest', aspect='auto', alpha=0.3)# 关闭坐标轴ax.axis('off')# 遍历矩阵C的每个元素,并在对应位置添加文本for i in range(C.shape[0]): for j in range(C.shape[1]): # 使用text函数在矩阵的每个位置添加数字,并设置字体大小和颜色
ax.text(j, i, str(int(C[i, j])), ha='center', va='center', color='black', fontsize=12)# 显示图像plt.show()
在这个例子中,alpha=0.3设置了imshow的透明度,这样文本可以清晰地显示在矩阵上面。ax.text函数用于在每个单元格的中心位置添加数字,ha=’center’和va=’center’确保文本水平和垂直居中。str(int(C[i, j]))将矩阵元素转换为整数并转换为字符串,以便在图像上显示。
请注意,由于imshow默认会将数据归一化到[0, 1]范围内,所以你可能需要根据实际情况调整文本的位置或大小,以确保它们能够清晰地显示在图像上。此外,aspect=’auto’确保了矩阵的纵横比是正确的,即每个单元格都是正方形。
这个代码又忘记了之前的任务了,只绘制了其中一个矩阵,不过效果已经出来了。我们要做的就是把多个代码整合起来就行了。
6. 任务拆开继续发问: 定义包含灰白两种颜色的映射
其实这个效果差不多了,我想着不要白色背景,不过问题还是没问清楚,但答案给出了提示。
获得答案:
要创建一个包含灰色和白色两种颜色的映射,你可以使用ListedColormap,并为它提供一个颜色列表,其中包含你想要的灰色和白色。这个颜色列表中的颜色将按照它们在列表中的顺序映射到数据的最小值和最大值。
下面是一个如何定义这样一个颜色映射的示例:
import numpy as npimport matplotlib.pyplot as pltfrom matplotlib.colors import ListedColormap# 创建一个示例数组data = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])# 定义灰色和白色的RGB值# 这里我们使用不同深浅的灰色和纯白色gray_levels = ['#808080', '#C0C0C0', '#FFFFFF'] # 浅灰,中灰,白色# 创建自定义颜色映射custom_cmap = ListedColormap(gray_levels)# 创建一个坐标轴对象fig, ax = plt.subplots()# 使用自定义颜色映射显示图像# 注意,由于我们的颜色映射只有三个级别,数据将被离散化到这三个级别ax.imshow(data, cmap=custom_cmap)# 关闭坐标轴ax.axis('off')# 显示图像plt.show()
在这个例子中,gray_levels 列表包含了三个颜色的十六进制代码,它们代表两种不同的灰色和一个白色。ListedColormap 使用这些颜色来创建一个颜色映射,该映射将最小的数据值映射到第一个颜色(浅灰色),最大的数据值映射到最后一个颜色(白色),中间的值则映射到中间的颜色(中灰色)。
请注意,由于我们的颜色映射只包含三个级别,imshow 会将原始数据离散化到这三个级别。如果你的数据范围很大或有很多不同的值,你可能需要定义一个包含更多灰色级别的颜色映射,以便更好地反映数据的差异。
如果你想要一个更平滑的过渡效果,你可以使用LinearSegmentedColormap来创建一个渐变的颜色映射,如下所示:
from matplotlib.colors import LinearSegmentedColormap# 定义灰色到白色的渐变颜色映射gray_white_cmap = LinearSegmentedColormap.from_list('gray_white', ['#808080', '#FFFFFF'])# 在imshow中使用渐变颜色映射ax.imshow(data, cmap=gray_white_cmap)
这将创建一个从灰色到白色的平滑渐变颜色映射。
从这里可以看到自己想怎么映射颜色都可以。
7. 因为相乘后的矩阵数值一般比较大,给他分配更大的宽度: 一个子图可以占 2 个 subplot 吗
8. 提出具体需求:用subplot2grid绘制上面的 3 个矩阵,第 4 个矩阵给 2 个子图的位置
我这里问的稀里糊涂的,数目都搞错了~~~~
文心一言还是可以的理解的,获得答案:
要使用 subplot2grid 在一个图中绘制三个矩阵,并让第四个矩阵占据两个子图的位置,你需要首先规划子图的网格布局。在这个例子中,我们可以创建一个 2x2 的网格,其中第一个、第二个和第三个矩阵各占据一个位置,而第四个矩阵将占据下面两个位置。
以下是实现这一布局的代码示例:
import numpy as npimport matplotlib.pyplot as pltfrom matplotlib.gridspec import GridSpec# 创建一些示例矩阵A = np.random.rand(2, 2)
B = np.random.rand(2, 2)
C = np.random.rand(2, 2)
D = np.random.rand(2, 2)# 创建一个新的图形fig = plt.figure(figsize=(8, 8))# 使用 GridSpec 创建 2x2 的网格布局gs = GridSpec(2, 2, width_ratios=[1, 1], height_ratios=[1, 2])# 在第一个位置绘制矩阵 Aax1 = fig.add_subplot(gs[0, 0])
ax1.set_title('Matrix A')
ax1.imshow(A, cmap='gray')# 在第二个位置绘制矩阵 Bax2 = fig.add_subplot(gs[0, 1])
ax2.set_title('Matrix B')
ax2.imshow(B, cmap='gray')# 在第三个位置绘制矩阵 Cax3 = fig.add_subplot(gs[1, 0])
ax3.set_title('Matrix C')
ax3.imshow(C, cmap='gray')# 在第四个位置绘制矩阵 D,跨越两个子图的位置ax4 = fig.add_subplot(gs[1, 1:])
ax4.set_title('Matrix D (Spanning 2 subplots)')
ax4.imshow(D, cmap='gray')# 调整子图之间的间距plt.tight_layout()# 显示图形plt.show()
在这个例子中,GridSpec 被用来创建一个 2x2 的网格,其中 height_ratios=[1, 2] 指定了第二行的高度是第一行的两倍,这样矩阵 D 就可以占据两个子图的位置。gs[1, 1:] 表示从第二行第一个位置开始到最后一列的所有位置。
请注意,这里我使用了 imshow 函数来显示矩阵,并且为它们指定了灰度颜色映射 (cmap=’gray’)。如果你想要矩阵中的数字作为文本显示,而不是使用颜色映射,你需要像之前那样使用 text 函数来在每个子图中手动放置数字。
如果你想要的是白色背景并且不使用颜色映射,那么你可以简单地在每个子图中使用 text 函数,并且不需要使用 imshow。下面是一个这样的例子:
import numpy as npimport matplotlib.pyplot as plt# 创建一些示例矩阵A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
C = np.array([[9, 10], [11, 12]])
D = np.array([[13, 14], [15, 16]])# 创建一个新的图形fig = plt.figure(figsize=(8, 8))# 使用 subplot2grid 创建子图ax1 = plt.subplot2grid((2, 2), (0, 0), rowspan=1, colspan=1)
ax2 = plt.subplot2grid((2, 2), (0, 1), rowspan=1, colspan=1)
ax3 = plt.subplot2grid((2, 2), (1, 0), rowspan=1, colspan=1)
ax4 = plt.subplot2grid((2, 2), (1, 0), rowspan=2, colspan=2) # 跨越两个子图的位置# 设置所有子图的背景色为白色ax1.set_facecolor('white')
ax2.set_facecolor('white')
ax3.set_facecolor('white')
ax4.set_facecolor('white')# 在每个子图中显示矩阵的元素for i in range(A.shape[0]): for j in range(A.shape[1]):
ax1.text(j, i, str(A[i, j]), ha='center', va='center', fontsize=12, color='black')
代码给出了提示,虽然不是完整的代码,但整个思路都提供了。
当然你还可以继续发问,或换更好的问法,不过我也没继续问,把上面的代码整合一下,一段代码就出来了。
import numpy as npimport matplotlib.pyplot as pltfrom matplotlib.colors import ListedColormap, LinearSegmentedColormap
X1 = np.array([[1, 2, 3],
[4, 5, 6]])
W1 = np.array([[5, 6, 7, 8, 9],
[7, 8, 9, 1, 2],
[1, 2, 3, 4, 5]])
B1 = np.array([[1, 2, 3, 4, 5]])# 计算矩阵相乘结果 H1 = np.dot(X1, W1) + B1# 绘制矩阵 X1plt.figure(figsize=(24, 3))
plt_row_columns = (1,13)
ax1 = plt.subplot2grid(plt_row_columns, (0, 0), rowspan=1, colspan=2)
ax2 = plt.subplot2grid(plt_row_columns, (0, 2), rowspan=1, colspan=1)
ax3 = plt.subplot2grid(plt_row_columns, (0, 3), rowspan=1, colspan=2)
ax4 = plt.subplot2grid(plt_row_columns, (0, 5), rowspan=1, colspan=1)
ax5 = plt.subplot2grid(plt_row_columns, (0, 6), rowspan=1, colspan=2)
ax6 = plt.subplot2grid(plt_row_columns, (0, 8), rowspan=1, colspan=1)
ax7 = plt.subplot2grid(plt_row_columns, (0, 9), rowspan=1, colspan=4)#color_map_odds_even = ListedColormap(['red' if i % 2 != 0 else 'blue' for i in range(int(data.max() + 1)])# cmap = ListedColormap(['grey'])def plot_matrix(mat, ax, mat_name):
# cmap = ListedColormap(['grey' if i % 2 != 0 else 'white' for i in range(int(mat.max()) + 1)])
cmap = LinearSegmentedColormap.from_list('gray',['#808080', '#C0C0C0'])
ax.set_title(f'Matrix {mat_name}', fontsize=20) # ax.title.set_position([0.5, 1.05])
im = ax.imshow(mat, cmap=cmap, aspect='equal', alpha=0.3)
ax.axis('off') #
for i in range(mat.shape[0]): for j in range(mat.shape[1]): # 使用text函数在矩阵的每个位置添加数字,并设置字体大小和颜色
ax.text(j, i, str(int(mat[i, j])), ha='center', va='center', color='black', fontsize=20)# 这里借鉴了填充数字的方式把符号填充到了矩阵中间def plot_symbol(symbol, ax, cmap=ListedColormap(['green'])):
ax.imshow(np.array([[0]]), cmap=cmap, aspect='equal', alpha=0)
ax.text(0,0, symbol, ha='center', va='center', color='black', fontsize=30)
ax.axis('off')
plot_matrix(X1, ax1, "X1")
plot_symbol("X", ax2)
plot_matrix(W1, ax3, "W1")
plot_symbol("+", ax4)
plot_matrix(B1, ax5, "B1")
plot_symbol("=", ax6)
plot_matrix(H1, ax7, "H1")# 不显示图例plt.gca().legend_ = None# plt.axis('off')# 展示图形plt.tight_layout()#plt.subplots_adjust(wspace=0.2, hspace=0.5) plt.show()
可以看到整个使用过程还是比较流畅的,但依然需要你懂一点 python 的基础知识,具体可看生信宝典视频号中一系列 Python 的基础教程。
生信分析Python实战练习 1 | 视频18
。
。
。
。
。
。
生信分析Python实战练习 10 | 视频28
高颜值免费 SCI 在线绘图(点击图片直达)
往期精品(点击图片直达文字对应教程)
机器学习