因为python好像没有nomogram的包,在搜索后发现并没有相关代码,因此在借鉴了几位网友的思路后,因为他们的代码实现上,都和真正的列线图有些差距,因此我进行了一些完善,最终达到这么一个效果:
# -*- coding: utf-8 -*-
"""
Created on Mon Aug 15 19:56:27 2022
#列线图绘制
@author: Azhuang
"""
import matplotlib.pyplot as plt
from matplotlib import ticker
class nomogram():
def __init__(self, var_count):
self.var_count = var_count
self.count = var_count
self.high = 0.3 / self.count
#title:变量名称
#minx:变量最小值
#maxx:变量最大值
#major:刻度线最大刻度
#minor:刻度线最小刻度
#beg:刻度对应起始分数
#end:刻度对应最终分数
def nomogram_draw(self, title, minx, maxx, major, minor, beg = 0, end = 100, position="bottom"):
self.var_count = self.var_count - 1
left = (beg) / 100 #对应刻度为100分,转化为对应坐标位置,图起始左边界相对位置是0.1
right = (end - beg) / 100 #length是长度,需要转化为相应坐标位置
down = (self.var_count / self.count) #显示方向,自上往下,1-(self.var_count / self.count) 是自下往上
rect = [left, down, right, self.high]
ax = plt.axes(rect)
# 只显示底部脊椎
ax.yaxis.set_major_locator(ticker.NullLocator())
ax.spines['right'].set_color('none')
ax.spines['left'].set_color('none')
if (position == "bottom"):
ax.spines['top'].set_color('none')
elif (position == "top"):
ax.spines['bottom'].set_color('none')
# 定义刻度最大最小精度
ax.xaxis.set_major_locator(ticker.MultipleLocator(major))
ax.xaxis.set_minor_locator(ticker.MultipleLocator(minor)) # 最小刻度精度
# 定义刻度位置
ax.xaxis.set_ticks_position(position)
ax.set_xlim(minx, maxx)
text_rect = [0, down, 0.1, 0.1] #用来打标签
text_ax = plt.axes(text_rect)
text_ax.yaxis.set_major_locator(ticker.NullLocator())
text_ax.axis('off')
text_ax.text(-2.0, -0.3, title, transform = text_ax.transAxes,
fontsize=9, fontname='Monospace', color='black')
def main():
fig = plt.figure(figsize=(12,6)) #定义画布
example = nomogram(10) #传入值代表变量个数,不能过多,会导致刻度互相遮盖
example.nomogram_draw(title="Points", minx=0, maxx=100, major=10, minor=2.5)
example.nomogram_draw(title="Age", minx=35, maxx=85, major=5, minor=5, beg = 15, end = 50)
example.nomogram_draw(title="Blood Glucose", minx=100, maxx=50, major=10, minor=10)
example.nomogram_draw(title="Gender", minx='F', maxx='M', major=1, minor=1, beg = 20, end = 60)
example.nomogram_draw(title="TotalPoints", minx=0, maxx=260, major=20, minor=4)
example.nomogram_draw(title="1-yearSurvival Probability", minx=0.85, maxx=0.5, major=0.05, minor=0.05)
example.nomogram_draw(title="3-yearSurvival Probability", minx=0.5, maxx=0.05, major=0.05, minor=0.05)
example.nomogram_draw(title="5-yearSurvival Probability", minx=0.25, maxx=0.05, major=0.05, minor=0.05)
if __name__ == '__main__':
main()
因为我对列线图还不太了解,仅仅是根据所看到的列线图来实现出一个效果,肯定有着更好、更完美的方法实现,而且R语言的rms包已经提供这部分功能,这个python代码更多只是我的固执,如果大家在使用过程中有遇到什么问题,欢迎给我留言!我也可以更加完善我的代码。