在使用python生成的图中添加一些数字
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在使用python生成的图中添加一些数字相关的知识,希望对你有一定的参考价值。
这是我在stackoverflow上发表的第一篇文章,所以请保持温和。
这是我的问题:我在网站上发现了一个非常好的python脚本,我不得不稍微修改以适应我的需要,现在我想再次修改它但我不知道如何
首先是代码
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
def bullseye_plot(ax, data, segBold=None, cmap=None, norm=None):
"""
Bullseye representation for the left ventricle.
Parameters
----------
ax : axes
data : list of int and float
The intensity values for each of the 17 segments
segBold: list of int, optional
A list with the segments to highlight
cmap : ColorMap or None, optional
Optional argument to set the desired colormap
norm : Normalize or None, optional
Optional argument to normalize data into the [0.0, 1.0] range
Notes
-----
This function create the 17 segment model for the left ventricle according
to the American Heart Association (AHA) [1]_
References
----------
.. [1] M. D. Cerqueira, N. J. Weissman, V. Dilsizian, A. K. Jacobs,
S. Kaul, W. K. Laskey, D. J. Pennell, J. A. Rumberger, T. Ryan,
and M. S. Verani, "Standardized myocardial segmentation and
nomenclature for tomographic imaging of the heart",
Circulation, vol. 105, no. 4, pp. 539-542, 2002.
"""
if segBold is None:
segBold = []
linewidth = 2
data = np.array(data).ravel()
if cmap is None:
cmap = plt.cm.viridis
if norm is None:
norm = mpl.colors.Normalize(vmin=data.min(), vmax=data.max())
theta = np.linspace(0, 2*np.pi, 768)
r = np.linspace(0, 1, 4)
# Create the bound for the segment 17
for i in range(r.shape[0]):
ax.plot(theta, np.repeat(r[i], theta.shape), '-k', lw=linewidth)
# Create the bounds for the segments 1-12
for i in range(6):
theta_i = i*60*np.pi/180
ax.plot([theta_i, theta_i], [r[1], 1], '-k', lw=linewidth)
# Create the bounds for the segments 13-16
for i in range(4):
theta_i = i*90*np.pi/180 - 45*np.pi/180
ax.plot([theta_i, theta_i], [r[0], r[1]], '-k', lw=linewidth)
# Fill the segments 1-6
r0 = r[2:4]
r0 = np.repeat(r0[:, np.newaxis], 128, axis=1).T
for i in range(6):
# First segment start at 60 degrees
theta0 = theta[i*128:i*128+128] + 60*np.pi/180
theta0 = np.repeat(theta0[:, np.newaxis], 2, axis=1)
z = np.ones((128, 2))*data[i]
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
if i+1 in segBold:
ax.plot(theta0, r0, '-k', lw=linewidth+2)
ax.plot(theta0[0], [r[2], r[3]], '-k', lw=linewidth+1)
ax.plot(theta0[-1], [r[2], r[3]], '-k', lw=linewidth+1)
# Fill the segments 7-12
r0 = r[1:3]
r0 = np.repeat(r0[:, np.newaxis], 128, axis=1).T
for i in range(6):
# First segment start at 60 degrees
theta0 = theta[i*128:i*128+128] + 60*np.pi/180
theta0 = np.repeat(theta0[:, np.newaxis], 2, axis=1)
z = np.ones((128, 2))*data[i+6]
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
if i+7 in segBold:
ax.plot(theta0, r0, '-k', lw=linewidth+2)
ax.plot(theta0[0], [r[1], r[2]], '-k', lw=linewidth+1)
ax.plot(theta0[-1], [r[1], r[2]], '-k', lw=linewidth+1)
# Fill the segments 13-16
r0 = r[0:2]
r0 = np.repeat(r0[:, np.newaxis], 192, axis=1).T
for i in range(4):
# First segment start at 45 degrees
theta0 = theta[i*192:i*192+192] + 45*np.pi/180
theta0 = np.repeat(theta0[:, np.newaxis], 2, axis=1)
z = np.ones((192, 2))*data[i+12]
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
if i+13 in segBold:
ax.plot(theta0, r0, '-k', lw=linewidth+2)
ax.plot(theta0[0], [r[0], r[1]], '-k', lw=linewidth+1)
ax.plot(theta0[-1], [r[0], r[1]], '-k', lw=linewidth+1)
ax.set_ylim([0, 1])
ax.set_yticklabels([])
ax.set_xticklabels([])
# Create the fake data
data = np.array(range(17)) + 1
# Make a figure and axes with dimensions as desired.
fig, ax = plt.subplots(figsize=(12, 8), nrows=1, ncols=1,
subplot_kw=dict(projection='polar'))
fig.canvas.set_window_title('Left Ventricle Bulls Eyes (AHA)')
# Set the colormap and norm to correspond to the data for which
# the colorbar will be used.
cmap = mpl.cm.viridis
norm = mpl.colors.Normalize(vmin=1, vmax=17)
# Create the 17 segment model
bullseye_plot(ax, data, cmap=cmap, norm=norm)
ax.set_title('Bulls Eye (AHA)')
plt.show()
它产生我们称之为靶心的地图,看看产生的输出:qazxsw poi
我想要做的是非常直接的解释:
-i想要在每个段中正确地添加一个或两个数字(最大值)(在此图中,有16个段)。
- 取决于数字的值(当只有一个数字时),我希望能够将每个段与不同的阴影/颜色相关联。例如,如果我有“2”,则相关段的颜色将为红色。如果我有“4”,相关片段的颜色也可能是红色但颜色较深。沿着这些方向的东西。
如果这样的事情是不可能的,至少我想根据与给定片段相关联的数量而具有不同的颜色。
我不是在python中知道的,所以我不知道该怎么做,我的问题是如此具体,以至于我真的不知道在哪里寻找答案。如果你能帮助我,我会非常感激。
PS:另外,如果您认为代码可能会以某种方式得到改进(或者有一些无用的部分),请告诉我。
先感谢您。
PS:为了给予在第一名创建代码的人的信誉,这里是原始链接Bulleye map
到目前为止,我做了类似于Latex的事情,这是我获得的图片,当他们是每个段的2个数字。我希望它能更容易“画出”我想要的东西。 How to generate bulleye map
更新:通过结合接受的答案和原始脚本中的一些想法,我终于得到了我想要的。这是脚本
Bulleye map - LateX version
至于结果,这里是import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
def bullseye_plot(ax, data, segBold=None, cmap=None, norm=None, labels=[], labelProps={}):
if segBold is None:
segBold = []
linewidth = 2
data = np.array(data).ravel()
if cmap is None:
cmap = plt.cm.viridis
if norm is None:
norm = mpl.colors.Normalize(vmin=data.min(), vmax=data.max())
theta = np.linspace(0, 2*np.pi, 768)
r = np.linspace(0, 1, 4)
# Create the bound for the segment 17
for i in range(r.shape[0]):
ax.plot(theta, np.repeat(r[i], theta.shape), '-k', lw=linewidth)
# Create the bounds for the segments 1-12
for i in range(6):
theta_i = i*60*np.pi/180
ax.plot([theta_i, theta_i], [r[1], 1], '-k', lw=linewidth)
# Create the bounds for the segments 13-16
for i in range(4):
theta_i = i*90*np.pi/180 - 45*np.pi/180
ax.plot([theta_i, theta_i], [r[0], r[1]], '-k', lw=linewidth)
# Fill the segments 1-6
r0 = r[2:4]
r0 = np.repeat(r0[:, np.newaxis], 128, axis=1).T
for i in range(6):
# First segment start at 60 degrees
theta0 = theta[i*128:i*128+128] + 60*np.pi/180
theta0 = np.repeat(theta0[:, np.newaxis], 2, axis=1)
z = np.ones((128, 2))*data[i]
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
if labels:
ax.annotate(labels[i], xy=(theta0[0,0]+30*np.pi/180,np.mean(r[2:4])), ha='center', va='center', **labelProps)
if i+1 in segBold:
ax.plot(theta0, r0, '-k', lw=linewidth+2)
ax.plot(theta0[0], [r[2], r[3]], '-k', lw=linewidth+1)
ax.plot(theta0[-1], [r[2], r[3]], '-k', lw=linewidth+1)
# Fill the segments 7-12
r0 = r[1:3]
r0 = np.repeat(r0[:, np.newaxis], 128, axis=1).T
for i in range(6):
# First segment start at 60 degrees
theta0 = theta[i*128:i*128+128] + 60*np.pi/180
theta0 = np.repeat(theta0[:, np.newaxis], 2, axis=1)
z = np.ones((128, 2))*data[i+6]
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
if labels:
ax.annotate(labels[i+6], xy=(theta0[0,0]+30*np.pi/180,np.mean(r[1:3])), ha='center', va='center', **labelProps)
if i+7 in segBold:
ax.plot(theta0, r0, '-k', lw=linewidth+2)
ax.plot(theta0[0], [r[1], r[2]], '-k', lw=linewidth+1)
ax.plot(theta0[-1], [r[1], r[2]], '-k', lw=linewidth+1)
# Fill the segments 13-16
r0 = r[0:2]
r0 = np.repeat(r0[:, np.newaxis], 192, axis=1).T
for i in range(4):
# First segment start at 45 degrees
theta0 = theta[i*192:i*192+192] + 45*np.pi/180
theta0 = np.repeat(theta0[:, np.newaxis], 2, axis=1)
z = np.ones((192, 2))*data[i+12]
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
if labels:
ax.annotate(labels[i+12], xy=(theta0[0,0]+45*np.pi/180,np.mean(r[0:2])), ha='center', va='center', **labelProps)
if i+13 in segBold:
ax.plot(theta0, r0, '-k', lw=linewidth+2)
ax.plot(theta0[0], [r[0], r[1]], '-k', lw=linewidth+1)
ax.plot(theta0[-1], [r[0], r[1]], '-k', lw=linewidth+1)
ax.set_ylim([0, 1])
ax.set_yticklabels([])
ax.set_xticklabels([])
# Create the fake data
labels = ['1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'10',
'11',
'12',
'13',
'14',
'15',
'16']
data=[]
for i in range(len(labels)):
x=int(labels[i])
data.append(x)
# Make a figure and axes with dimensions as desired.
fig, ax = plt.subplots(figsize=(8, 8), nrows=1, ncols=1,
subplot_kw=dict(projection='polar'))
fig.canvas.set_window_title('Left Ventricle Bulls Eyes (AHA)')
# Create the axis for the colorbars
axl = fig.add_axes([0.14, 0.15, 0.2, 0.05])
# Set the colormap and norm to correspond to the data for which
# the colorbar will be used.
cmap = mpl.cm.viridis
norm = mpl.colors.Normalize(vmin=min(data), vmax=max(data))
# ColorbarBase derives from ScalarMappable and puts a colorbar
# in a specified axes, so it has everything needed for a
# standalone colorbar. There are many more kwargs, but the
# following gives a basic continuous colorbar with ticks
# and labels.
cb1 = mpl.colorbar.ColorbarBase(axl, cmap=cmap, norm=norm,
orientation='horizontal')
cb1.set_label('Some Units')
# Create the 16 segment model
bullseye_plot(ax, data, cmap=cmap, norm=norm, labels=labels, labelProps={'size':15, "weight":'bold'})
ax.set_title('Bulls Eye (AHA)')
plt.show()
我修改了代码,在单元格的(近似)中心添加标签。您可以传递一组标签(作为字符串)和一个Final result字典来调整标签的外观。
至于细胞的颜色,它们由any parameters accepted by matplotlib's Text和色图确定。在原始代码中,您有一个线性色图(data
)。相反,您可以使用viridis
生成自己的颜色条,并将每种颜色映射到数据中的特定值。
ListedColormap
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
def bullseye_plot(ax, data, segBold=None, cmap=None, norm=None, labels=[], labelProps={}):
"""
Bullseye representation for the left ventricle.
Parameters
----------
ax : axes
data : list of int and float
The intensity values for each of the 17 segments
segBold: list of int, optional
A list with the segments to highlight
cmap : ColorMap or None, optional
Optional argument to set the desired colormap
norm : Normalize or None, optional
Optional argument to normalize data into the [0.0, 1.0] range
Notes
-----
This function create the 17 segment model for the left ventricle according
to the American Heart Association (AHA) [1]_
References
----------
.. [1] M. D. Cerqueira, N. J. Weissman, V. Dilsizian, A. K. Jacobs,
S. Kaul, W. K. Laskey, D. J. Pennell, J. A. Rumberger, T. Ryan,
and M. S. Verani, "Standardized myocardial segmentation and
nomenclature for tomographic imaging of the heart",
Circulation, vol. 105, no. 4, pp. 539-542, 2002.
"""
if segBold is None:
segBold = []
linewidth = 2
data = np.array(data).ravel()
if cmap is None:
cmap = plt.cm.viridis
if norm is None:
norm = mpl.colors.Normalize(vmin=data.min(), vmax=data.max())
theta = np.linspace(0, 2*np.pi, 768)
r = np.linspace(0, 1, 4)
# Create the bound for the segment 17
for i in range(r.shape[0]):
ax.plot(theta, np.repeat(r[i], theta.shape), '-k', lw=linewidth)
# Create the bounds for the segments 1-12
for i in range(6):
theta_i = i*60*np.pi/180
ax.plot([theta_i, theta_i], [r[1], 1], '-k', lw=linewidth)
# Create the bounds for the segments 13-16
for i in range(4):
theta_i = i*90*np.pi/180 - 45*np.pi/180
ax.plot([theta_i, theta_i], [r[0], r[1]], '-k', lw=linewidth)
# Fill the segments 1-6
r0 = r[2:4]
r0 = np.repeat(r0[:, np.newaxis], 128, axis=1).T
for i in range(6):
# First segment start at 60 degrees
theta0 = theta[i*128:i*128+128] + 60*np.pi/180
theta0 = np.repeat(theta0[:, np.newaxis], 2, axis=1)
z = np.ones((128, 2))*data[i]
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
if labels:
ax.annotate(labels[i], xy=(theta0[0,0]+30*np.pi/180,np.mean(r[2:4])), ha='center', va='center', **labelProps)
if i+1 in segBold:
ax.plot(theta0, r0, '-k', lw=linewidth+2)
ax.plot(theta0[0], [r[2], r[3]], '-k', lw=linewidth+1)
ax.plot(theta0[-1], [r[2], r[3]], '-k', lw=linewidth+1)
# Fill the segments 7-12
r0 = r[1:3]
r0 = np.repeat(r0[:, np.newaxis], 128, axis=1).T
for i in range(6):
# First segment start at 60 degrees
theta0 = theta[i*128:i*128+128] + 60*np.pi/180
theta0 = np.repeat(theta0[:, np.newaxis], 2, axis=1)
z = np.ones((128, 2))*data[i+6]
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
if labels:
ax.annotate(labels[i+6], xy=(theta0[0,0]+30*np.pi/180,np.mean(r[1:3])), ha='center', va='center', **labelProps)
if i+7 in segBold:
ax.plot(theta0, r0, '-k', lw=linewidth+2)
ax.plot(theta0[0], [r[1], r[2]], '-k', lw=linewidth+1)
ax.plot(theta0[-1], [r[1], r[2]], '-k', lw=linewidth+1)
# Fill the segments 13-16
r0 = r[0:2]
r0 = np.repeat(r0[:, np.newaxis], 192, axis=1).T
for i in range(4):
# First segment start at 45 degrees
theta0 = theta[i*192:i*192+192] + 45*np.pi/180
theta0 = np.repeat(theta0[:, np.newaxis], 2, axis=1)
z = np.ones((192, 2))*data[i+12]
ax.pcolormesh(theta0, r0, z, cmap=cmap, norm=norm)
if labels:
ax.annotate(labels[i+12], xy=(theta0[0,0]+45*np.pi/180,np.mean(r[0:2])), ha='center', va='center', **labelProps)
if i+13 in segBold:
ax.plot(theta0, r0, '-k', lw=linewidth+2)
ax.plot(theta0[0], [r[0], r[1]], '-k', lw=linewidth+1)
ax.plot(theta0[-1], [r[0], r[1]], '-k', lw=linewidth+1)
ax.set_ylim([0, 1])
ax.set_yticklabels([])
ax.set_xticklabels([])
# Create the fake data
data = [1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4]
labels = ['label 1',
'label 2',
'label 3',
'label 4',
'label 5',
'label 6',
'label 7',
'label 8',
'label 9',
'label 10',
'label 11',
'label 12',
'label 13',
'label 14',
'label 15',
'label 16',
'label 17']
# Make a figure and axes with dimensions as desired.
fig, ax = plt.subplots(figsize=(8, 8), nrows=1, ncols=1,
subplot_kw=dict(projection='polar'))
fig.canvas.set_window_title('Left Ventricle Bulls Eyes (AHA)')
# Set the colormap and norm to correspond to the data for which
# the colorbar will be used.
cmap = mpl.colors.ListedColormap(['xkcd:dusty purple',
'xkcd:light aquamarine',
'xkcd:pale salmon',
'xkcd:dusty orange',
'xkcd:sapphire',
'xkcd:azure'])
norm = mpl.colors.Normalize(vmin=1, vmax=6)
# Create the 17 segment model
bullseye_plot(ax, data, cmap=cmap, norm=norm, labels=labels, labelProps={'size':15, "weight":'bold'})
ax.set_title('Bulls Eye (AHA)')
plt.show()
我认为你要找的是从第55行开始:
注意数字60,它似乎是段的宽度。您可以将其修改为:
for i in range(6):
theta_i = i*60*np.pi/180
ax.plot([theta_i, theta_i], [r[1], 1], '-k', lw=linewidth)
我没有你使用的库,所以我无法测试。但希望你发现这很有用。
PS。确保sum(num1 ... num6)= 360
您可以将其添加到for i in range(6):
print "Enter value : "
read num
theta_i = i*num*np.pi/180
ax.plot([theta_i, theta_i], [r[1], 1], '-k', lw=linewidth)
函数的末尾
bullseye_plot
这显然没有优化,但它可以帮助这个想法
以上是关于在使用python生成的图中添加一些数字的主要内容,如果未能解决你的问题,请参考以下文章