扇形圖自定義色彩條
# 代碼均為本人碩士期間繪制,為便于閱讀和改進(jìn)盡可能逐行添加了注釋。
# 部分代碼可能寫的較繁瑣,如果有更簡潔的寫法歡迎留言!
# 感謝在我科研繪圖過程中提供幫助的各位博主!
# 導(dǎo)包
import matplotlib.pyplot as plt
from matplotlib import rcParams
# 設(shè)置配置文件
config = {
? ? # 襯線字體(襯線字體, 宋體和Times New Roman屬于這類字體)
? ? "font.family": 'serif',
? ? # matplotlib渲染數(shù)學(xué)字體時使用的字體,和Times New Roman差別不大
? ? "mathtext.fontset": 'stix',
? ? # 設(shè)置繪圖時全局字體為宋體(SimSun)
? ? "font.serif": ['SimSun'],
}
# 修改運(yùn)行時配置參數(shù)的方法(Matplotlib使用matplotlibrc配置文件來自定義圖形的各種屬性,稱之為rc配置或rc參數(shù)(rcParams))
rcParams.update(config)
# 為每個扇形提供顏色,顏色順序與排序后的x順序?qū)?yīng)
colors = ['#c4cc38', '#ebe12a', '#ebe12a', '#ebe12a', '#eab026', '#e3852b', '#d85d2a', '#ce2626']
def draw_pic(x, y):
? ? # 繪制餅圖
? ? '''
? ? plt.pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1,
? ? startangle=0, radius=1, counterclock=True, wedgeprops=None, textprops=None, center=0, 0, frame=False,
? ? rotatelabels=False, *, normalize=None, data=None)
? ? 傳入的參數(shù)y為每個扇形的占比數(shù)組;
? ? labels為每個扇形提供標(biāo)簽的字符串序列;
? ? autopct如果是一個格式字符串,標(biāo)簽將是fmt % pct。如果它是一個函數(shù),它將被調(diào)用。在代碼中%0.1f%%表示保留1位小數(shù);
? ? colors為每個扇形提供顏色;
? ? wedgeprops設(shè)置餅圖內(nèi)外邊界的屬性,如邊界線的粗細(xì)、顏色等。在代碼中,我們設(shè)置邊框?yàn)楹谏?/p>
? ? textprops設(shè)置餅圖中文本的屬性,如字體大小、顏色等。在代碼中,我們設(shè)置字號為12,字體為新羅馬;
? ? labeldistance設(shè)置各扇形標(biāo)簽(圖例)與圓心的距離。
? ? '''
? ? plt.pie(y, labels=x, autopct="%0.1f%%", colors=colors, wedgeprops={'edgecolor': "black"},
? ? ? ? ? ? textprops={'fontsize': 12, 'fontproperties': 'Times New Roman'}, labeldistance=1.05)
? ? # 關(guān)閉坐標(biāo)軸
? ? plt.axis('off')
? ? # Matplotlib自定義添加colorbar
? ? # 添加子圖plt.axis([a, b, c, d]) 設(shè)置x軸的范圍為[a, b],y軸的范圍為[c, d]
? ? cax = plt.axes([0.805, 0.25, 0.03, 0.5])
? ? '''
? ? fill_between用于在兩條曲線間填充顏色
? ? fill_between(y, x1, x2=0, where=None, step=None, interpolate=False,
? ? ? ? ? ? ?data=None, **kwargs)
? ? y:表示y軸坐標(biāo)的序列;
? ? x1:表示第一條曲線的x軸坐標(biāo);
? ? x2:表示第二條曲線的x軸坐標(biāo);
·where:布爾值,表示要填充區(qū)域的條件。
? ? '''
? ? cax.fill_between([0, 0.5], 0.5, color=colors[7])
? ? cax.fill_between([0, 0.5], 0.5, 1, color=colors[6])
? ? cax.fill_between([0, 0.5], 1, 1.5, color=colors[5])
? ? cax.fill_between([0, 0.5], 1.5, 2, color=colors[4])
? ? cax.fill_between([0, 0.5], 2, 2.5, color=colors[3])
? ? cax.fill_between([0, 0.5], 2.5, 3, color=colors[0])
? ? # 設(shè)置y軸正向顯示范圍
? ? cax.set_ylim(0, 3)
? ? # 設(shè)置x軸和y軸刻度
? ? cax.set_xticks([])
? ? cax.set_yticks([0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0])
? ? cax.set_yticklabels(['高頻', '', '', ' ', '', '', '低頻'], fontsize=12)
? ? # 將y軸的數(shù)值顯示在右邊
? ? cax.yaxis.tick_right()
? ? # 獲取y軸所有刻度信息
? ? yticks = cax.yaxis.get_major_ticks()
? ? # # 隱藏第1~第5個刻線
? ? yticks[1].set_visible(False)
? ? yticks[2].set_visible(False)
? ? yticks[3].set_visible(False)
? ? yticks[4].set_visible(False)
? ? yticks[5].set_visible(False)
? ? # 存儲為SVG格式(矢量圖不失真),bbox_inches='tight', pad_inches=0可以去除圖片的白邊
? ? plt.savefig('CTU-13 場景特征頻數(shù).svg', bbox_inches='tight', pad_inches=0)
? ? plt.show()
if __name__ == '__main__':
? ? # 待統(tǒng)計(jì)序列
? ? feature_list = ['IRC', 'SPAM', 'CF', 'IRC', 'SPAM', 'CF', 'IRC', 'PS', 'US', 'IRC', 'DDoS', 'US', 'SPAM', 'PS',
? ? ? ? ? ? ? ? ? ? 'HTTP',
? ? ? ? ? ? ? ? ? ? 'PS', 'HTTP', 'PS', 'IRC', 'SPAM', 'CF', 'PS', 'IRC', 'DDoS', 'US', 'IRC', 'DDoS', 'US', 'P2P',
? ? ? ? ? ? ? ? ? ? 'SPAM',
? ? ? ? ? ? ? ? ? ? 'PS', 'HTTP']
? ? # 統(tǒng)計(jì)待統(tǒng)計(jì)序列中每類的頻數(shù),存放在字典a中
? ? a = {}
? ? for i in feature_list:
? ? ? ? a[i] = feature_list.count(i)
? ? # print(a)
? ? # 字典按值排序,將排序后的字典按照key和value的對應(yīng)關(guān)系存放在a_order中
? ? a_order = sorted(a.items(), key=lambda x: x[1])
? ? # print(a_order)
? ? # 分別將a_order中每個元組的第一項(xiàng)和第二項(xiàng),存放在x,y中,即x為每類名稱,y為對應(yīng)的頻數(shù)
? ? x = []
? ? y = []
? ? for i in range(len(a_order)):
? ? ? ? x.append(a_order[i][0])
? ? ? ? y.append(a_order[i][1])
? ? # print(x, y)
? ? # 繪圖
? ? draw_pic(x, y)
