python学习笔记

【python实战】matplotlib绘图(二)

2020-05-13  本文已影响0人  Hobbit的理查德

【python实战】matplotlib绘图(一)

话不多说,接着画图,不得不说,matplotlib画图,写的代码是真多,

等画完了一段时间后,再来总结一下!

今天展示3张图片:

1.环形图+条形图(pie_barh)

pie_barh.png
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.patches import ConnectionPatch
import numpy as np
#设置字体、图形样式
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['font.family']='sans-serif'
matplotlib.rcParams['axes.unicode_minus'] = False
# 饼图/环形图
fig=plt.figure()
ax1=fig.add_subplot(121)
ax2=fig.add_axes([0.55, 0.33, 0.35, 0.35])#left, bottom, width, height
# 数据
data={
        "data": [
            {"question": "独生子女", "value": 0.5078},
            {"question": "非独生子女", "value":0.4922}
        ],
    }
ratios=[d["value"] for d in data['data']]
labels=[d["question"] for d in data['data']]
color=[RGB_to_Hex('41,130,177'),RGB_to_Hex('205,205,205')]

# 环形宽度
size=0.3
ax1.pie(ratios,startangle=90,
    # labeldistance=0.4,#文本标签
    colors=color,
    # autopct='\n\n\n%.2f%%',#百分比
    pctdistance=0.8,
    # labels=labels,
    wedgeprops= {'width': size, 'edgecolor': 'w'}
    )

# 加文本标签
bar_text=labels[0]+'\n'+format(ratios[0],'.2%')
ax1.text(0,0,bar_text,
    size=12,ha="center", va="center",
    bbox=dict(boxstyle="round",ec='white',fc='white'))

############################ 条形图
# 数据
data={
        "data": [
            {"question": "1个", "value": 0.6353},
            {"question": "2个", "value":0.2177},
            {"question": "3个及以上", "value":0.1470}
        ],
    }
# 数据设置
ratios=[d["value"] for d in data['data']]
labels=[d["question"] for d in data['data']]
#排序
data_sort=[list(z) for z in zip(labels, ratios)]
data_sort.sort(key=lambda x:(x[1]),reverse=False)
labels=[x[0] for x in data_sort]
ratios=[x[1] for x in data_sort]
# 作图
height=0.4
bar=ax2.barh(y=labels,width=ratios,height=height,color=RGB_to_Hex('205,205,205'))
# 去掉边框
ax2.spines['top'].set_visible(False)
ax2.spines['right'].set_visible(False)
ax2.spines['bottom'].set_visible(False)
#不要X横坐标上的label标签
plt.xticks(())
# 添加数据标签
for b in bar:
    width=b.get_width()
    plt.text(width+0.08,b.get_y()+height/2,format(width,'.2%'),ha='center')
# 取饼图和条形图的值
theta1, theta2 = ax1.patches[0].theta1, ax1.patches[0].theta2
center, r = ax1.patches[0].center, ax1.patches[0].r
bar_high=plt.axis()[3]
bar_low=plt.axis()[2]
#划下面的线
# 定义线的样式
def pie2bar_line(con):
    con.set_color(RGB_to_Hex('205,205,205'))
    con.set_linewidth(1)
    con.set_linestyle('--')
    ax2.add_artist(con)
x = r * np.cos(np.pi / 180 * theta2) + center[0]
y = np.sin(np.pi / 180 * theta2) + center[1]
con = ConnectionPatch(xyA=(0, bar_low), coordsA=ax2.transData,
                      xyB=(x, y), coordsB=ax1.transData)
pie2bar_line(con)
#划上面的线
x = r * np.cos(np.pi / 180 * theta1) + center[0]
y = np.sin(np.pi / 180 * theta1) + center[1]
con = ConnectionPatch(xyA=(0, bar_high), coordsA=ax2.transData,
                      xyB=(x, y), coordsB=ax1.transData)
pie2bar_line(con)
# 加文本标签
bar_max_width=max([i.get_width() for i in ax2.patches])
print(bar_max_width)
ax2.text(bar_max_width/2,bar_high+height,'兄弟姐妹数量',
    size=12,ha="center", va="center",
    bbox=dict(boxstyle="round",ec='white',fc='white'))
# 先保存再show,避免图片保存成空白
plt.savefig("pie_barh.png",dpi=600,bbox_inches = 'tight')
plt.show()

2.底图+柱形图+文本(pic_bar_text)

pic_bar_text.png
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import matplotlib.patches as patches
import matplotlib.cbook as cbook
import os
#设置字体、图形样式
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['font.family']='sans-serif'
matplotlib.rcParams['axes.unicode_minus'] = False
# 数据
xlabel=["直辖市/省会城市","地级市","县城或县级市","乡镇","农村"]
gaozhong=[0.1662,0.2245,0.2737,0.0909,0.2447]
xianzai=[0.1715,0.2183,0.2628,0.097,0.2503]
# 设置
x=np.arange(len(xlabel))
bar_width=0.4
# 作图
fig=plt.figure()
# 加底图
ax=fig.add_subplot()
current_path=os.getcwd()
with cbook.get_sample_data(current_path+'\\china_map.png') as image_file:
    image = plt.imread(image_file)
im=ax.imshow(image,alpha=0.3)
ax.axis('off')
# 加柱状图
ax1=fig.add_subplot(212,facecolor=(1,1,1,0))#子图设置透明,显示出底图
rects1 = ax1.bar(x - bar_width/2, gaozhong, bar_width, 
    label='高中前居地',color=RGB_to_Hex('62,142,185'))
rects2 = ax1.bar(x + bar_width/2, xianzai, bar_width, 
    label='现居地',color=RGB_to_Hex('141,210,231'))
# 设置x轴
ax1.set_xticks(x)
ax1.set_xticklabels(xlabel)
# 去掉边框
ax1.spines['top'].set_visible(False)
ax1.spines['left'].set_visible(False)
ax1.spines['right'].set_visible(False)
# 加图例
ax1.legend(loc='center',ncol=2,edgecolor='w',bbox_to_anchor=(0.5,-0.25))
#不要y坐标上的label标签
plt.yticks(())
ax1.set_ylim([0,0.3])
# 加标签
font_size=9
for i,y in zip(x,gaozhong):
    ax1.text(i-bar_width/2,y+0.01,format(y,'.2%'),ha="center", va="center",size=font_size)
for i,y in zip(x,xianzai):
    ax1.text(i+bar_width/2,y+0.01,format(y,'.2%'),ha="center", va="center",size=font_size)
# 加线框
rect1_width=bar_width*7+0.15
rect1_height=max([i.get_height() for i in ax1.patches])+0.025
rect2_width=bar_width*5
rect2_height=rect1_height
rect1=patches.Rectangle([0-bar_width-0.1, 0], rect1_width, rect1_height,
    ec=RGB_to_Hex('62,142,185'),fc=(0,0,0,0))
ax1.add_patch(rect1)
rect2=patches.Rectangle([0-bar_width-0.1+rect1_width+0.02,0], rect2_width, rect2_height,
    ec=RGB_to_Hex('62,142,185'),fc=(0,0,0,0),linestyle='--')
ax1.add_patch(rect2)
# 加文本标签
ax2=fig.add_subplot(211,facecolor=(1,1,1,0))
ax2.axis('off')
# 文本内容
text1='城市'+'\n'+'前居地:'+format(sum(gaozhong[0:3]),'.2%')+'\n'+'现居地:'+format(sum(xianzai[0:3]),'.2%')
text2='农村'+'\n'+'前居地:'+format(sum(gaozhong[3:]),'.2%')+'\n'+'现居地:'+format(sum(xianzai[3:]),'.2%')
# 加本文
ax2.text(0.3,0.2,text1,
        size=12,ha="center", va="center",
        bbox=dict(boxstyle="round",ec=RGB_to_Hex('62,142,185'),fc=(1,1,1,0)))
ax2.text(0.8,0.2,text2,
        size=12,ha="center", va="center",
        bbox=dict(boxstyle="round",linestyle='--',ec=RGB_to_Hex('62,142,185'),fc=(1,1,1,0)))
plt.savefig("pic_bar_text.png",dpi=600,bbox_inches = 'tight')
plt.show()

3.多个条形图(multibarhs)

multibarh.png
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
import matplotlib.transforms as mtransforms
#设置字体、图形样式
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['font.family']='sans-serif'
matplotlib.rcParams['axes.unicode_minus'] = False
# 作图
fig=plt.figure()
def draw_barh(subplotid,category):
    ax=fig.add_subplot(subplotid)
    # plt.subplots_adjust(left=0.33,bottom=0.11) #调整子图
    # 自动调整子图
    labels=ax.set_yticklabels(ylabel)
    def on_draw(event):
        bboxes = []
        for label in labels:
            bbox = label.get_window_extent()
            # the figure transform goes from relative coords->pixels and we
            # want the inverse of that
            bboxi = bbox.inverse_transformed(fig.transFigure)
            bboxes.append(bboxi)
            # this is the bbox that bounds all the bboxes, again in relative
            # figure coords
            bbox = mtransforms.Bbox.union(bboxes)
            if fig.subplotpars.left < bbox.width:
                # we need to move it over
                fig.subplots_adjust(left=1.1*bbox.width)  # pad a little
                fig.canvas.draw()
    fig.canvas.mpl_connect('draw_event', on_draw)
    # 条形图
    barh1=ax.barh(ylabel,values1,label='乡村',color=RGB_to_Hex('84,155,193'))
    barh2=ax.barh(ylabel,values2,label='城市',left=values1,color=RGB_to_Hex('154,215,233'))
    # 去掉边框
    orientation=['top','bottom','right']
    for o in orientation:
        ax.spines[o].set_visible(False)
    # x轴没有标签
    ax.set_xticks(())
    # y轴标题
    ax.set_ylabel(category)
    # 添加barh的数据标签
    def text_center(ax,x,y,z,size):
        ax.text(x,y,format(z,'.2%'),size=size,ha="center", va="center",
                bbox=dict(boxstyle="round",ec=(0,0,0,0),fc=(0,0,0,0)))
    def add_barh_text(size):
        for b1,b2 in zip(barh1,barh2):
            width1=b1.get_width()
            width2=b2.get_width()
            text_center(ax,width1/2,b1.get_y()+(b1.get_height()/2),width1,size)
            text_center(ax,width2/2+width1,b2.get_y()+(b2.get_height()/2),width2,size)
    add_barh_text(9)
    return ax

# 数据
ylabel=['独立设置医科院校','综合性大学医学院']
values1=[0.3618109,0.6381891]
values2=[0.3905331,0.6094669]
category='类别'
subplotid=411
draw_barh(subplotid,category)

ylabel=['8年制','7年制','5年制']
values1=[0.2627856,0.3477032,0.4435133]
values2=[0.7372144,0.6522968,0.5564867]
category='层次'
subplotid=412
draw_barh(subplotid,category)

ylabel=['直辖市','东部','中部','西部']
values1=[0.154762,0.338909,0.330464,0.479900 ]
values2=[0.8452381,0.6610915,0.6695359,0.5201005]
category='地区'
subplotid=413
draw_barh(subplotid,category)

ylabel=['8年制','7年制','5年制']
values1=[0.243040,0.337754,0.368057]
values2=[0.7569601,0.6622458,0.6319435]
category='学制'
subplotid=414
ax=draw_barh(subplotid,category)
ax.legend(ncol=2, bbox_to_anchor=(0.4, -0.4),edgecolor='w',
              loc='lower center', fontsize='small')

plt.savefig("multibarh.png",dpi=600,bbox_inches = 'tight')
plt.show()
上一篇下一篇

猜你喜欢

热点阅读