朱宝恒 发表于 2020-6-19 23:07:20

高中生比赛求救急急急

import matplotlib.pyplot as plt
import random
import pandas as pd
import pickle
import matplotlib.ticker as ticker
import matplotlib.animation as animation
def randomcolor():#颜色随机生成
    colorlist = ['1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']
    color =''
    for i in range(6):
      color += random.choice(colorlist)
    return '#'+ color
def get_pandafile():
    data0 = pd.read_excel('china_provincedata.xlsx', sheet_name='china_provincedata',usecols=['provinceShortName','累计确诊','dateId'])
    pickle_file = open('pdfile.pkl','wb')
    pickle.dump(data0,pickle_file)
    pickle_file.close()

def load_data():
    pickle_file = open('pdfile.pkl','rb')
    pdfile = pickle.load(pickle_file)
    return pdfile
df=load_data()
def get_colordict():


    area_list1 = set(df['provinceShortName'])
    color_list = []
    for i in range(len(area_list1)):
      str_1 = randomcolor()
      color_list.append(str_1)
      str_1 = randomcolor()
    area_list2 =

    color_dict = dict(zip(area_list2,color_list))
    return color_dict

def illpeople(current_day):
    fig, ax = plt.subplots(figsize=(15, 8))
    dff = df.eq(current_day)].sort_values(by='累计确诊', ascending=True).tail(12)
    ax.clear()
    ax.barh(dff['provinceShortName'],dff['累计确诊'],color = for x in dff['provinceShortName']])
    dx = dff['累计确诊'].max()/200
    for i, (value, name) in enumerate(zip(dff['累计确诊'], dff['provinceShortName'])):
      ax.text(value - dx, i, name, size=14, weight=600, ha='right', va='bottom')

      ax.text(value + dx, i, f'{value:,.0f}', size=14, ha='left', va='center')
    ax.text(1, 0.4, current_day, transform=ax.transAxes, color='#777777', size=46, ha='right', weight=800)
    ax.text(0, 1.06, 'Number of people', transform=ax.transAxes, size=12, color='#777777')

    # set_major_formatter表示刻度尺格式;
    ax.xaxis.set_major_formatter(ticker.StrMethodFormatter('{x:,.0f}'))
    ax.xaxis.set_ticks_position('top')
    ax.tick_params(axis='x', colors='#777777', labelsize=12)
    ax.set_yticks([])
    # margins表示自动缩放余额;
    ax.margins(0, 0.01)
    # 设置后面的网格
    ax.grid(which='major', axis='x', linestyle='-')
    # 刻度线和网格线是在图标上方还是下方,True为下方
    ax.set_axisbelow(True)
    ax.text(0, 1.15, 'Number of people infected with the COVID-19',
            transform=ax.transAxes, size=24, weight=600, ha='left', va='top')
    ax.text(1, 0, 'by@Baoheng Zhu', transform=ax.transAxes, color='#777777', ha='right',
            bbox=dict(facecolor='white', alpha=0.8, edgecolor='white'))
    # 取消图表周围的方框显示
    plt.box(False)

fig, ax = plt.subplots(figsize=(15, 8))




if __name__ == '__main__':
    randomcolor()
    get_pandafile()
    load_data()
    get_colordict()
    fig=illpeople(20200122)
    animator = animation.FuncAnimation(fig, illpeople, frames=range(20200122, 20200608))
    plt.show()

如题,省里组织python竞赛,说可以借鉴他人代码,我就在网上找了一个课题,自己改编,但是赛事要求只能用matplotlib
库,我要做的是新冠疫情动态图,没有ipython,没办法动,只能呈现一张图片,各位大神快来帮帮我吧,怎么才能用matploblib自身显示动画呢,跪谢

Twilight6 发表于 2020-6-20 00:37:41



你参考这个代码吧,我也是去隔壁度娘搬运来的,这个就算动态的图了:

import matplotlib.pyplot as plt
import numpy as np

ax=[]   #保存图1数据
ay=[]
bx=[]   #保存图2数据
by=[]
num=0   #计数
plt.ion()    # 开启一个画图的窗口进入交互模式,用于实时更新数据
# plt.rcParams['savefig.dpi'] = 200 #图片像素
# plt.rcParams['figure.dpi'] = 200 #分辨率
plt.rcParams['figure.figsize'] = (10, 10)      # 图像显示大小
plt.rcParams['font.sans-serif']=['SimHei']   #防止中文标签乱码,还有通过导入字体文件的方法
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['lines.linewidth'] = 0.5   #设置曲线线条宽度
while num<100:
    plt.clf()    #清除刷新前的图表,防止数据量过大消耗内存
    plt.suptitle("总标题",fontsize=30)             #添加总标题,并设置文字大小
    g1=np.random.random()#生成随机数画图
#图表1
    ax.append(num)      #追加x坐标值
    ay.append(g1)       #追加y坐标值
    agraphic=plt.subplot(2,1,1)
    agraphic.set_title('子图表标题1')      #添加子标题
    agraphic.set_xlabel('x轴',fontsize=10)   #添加轴标签
    agraphic.set_ylabel('y轴', fontsize=20)
    plt.plot(ax,ay,'g-')                #等于agraghic.plot(ax,ay,'g-')
#图表2
    bx.append(num)
    by.append(g1)
    bgraghic=plt.subplot(2, 1, 2)
    bgraghic.set_title('子图表标题2')
    bgraghic.plot(bx,by,'r^')

    plt.pause(0.4)   #设置暂停时间,太快图表无法正常显示
    if num == 15:
      plt.savefig('picture.png', dpi=300)# 设置保存图片的分辨率
      #break
    num=num+1

plt.ioff()       # 关闭画图的窗口,即关闭交互模式
plt.show()       # 显示图片,防止闪退

java2python 发表于 2020-6-20 01:19:35

本帖最后由 java2python 于 2020-6-20 03:39 编辑

你的程序想表达的数据,可能比较复杂,真的不懂,下面代码是反应每天前五位省份的数据变动情况的(当然由于其他省份和湖北比比例很小,看上去变动不明显):
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import animation
import pickle

def load_data():
    pickle_file = open('pdfile.pkl','rb')
    pdfile = pickle.load(pickle_file)
    return pdfile

start_day = 20200122
month_day=
def all_day(start,end):
    days = []
    cur_day = start
    while cur_day < end:
      mon = (cur_day//100) % 100
      day = cur_day % 100
      if day == month_day:
            mon += 1
            day = 1
      else:
            day +=1
      cur_day = 20200000+mon*100+day
      days.append(cur_day)
    return days
days = all_day(20200122,20200608)

fig=plt.figure(1,figsize=(4,3))
ax=fig.add_subplot(111)
ax.set_title('bar_animate_test')
ax.set_xlabel('xlable')
N=5
frames=len(days)
x=np.arange(1,N+1)

df=load_data()
collection=[]
collection.append()
for i in range(frames):
    dff = df.eq(days)].sort_values(by='confirmedCount', ascending=True).tail(5)
    ax.clear()
    c=[]
    for l, (value, name) in enumerate(zip(dff['confirmedCount'], dff['provinceShortName'])):
      c.append(value)

    collection.append(c)
print(collection)
xstd=
bars=ax.bar(x,collection,0.30)
def animate(fi):
    ax.set_ylim(0,max(collection)+3)
    for rect ,yi in zip(bars,collection):
      rect.set_height(yi)
    return bars
anim=animation.FuncAnimation(fig,animate,frames=frames,interval=300,repeat=False)
plt.show()

java2python 发表于 2020-6-20 13:01:21

你的程序,应该是拷贝Bar Chart Race(条形竞赛图) in Python with Matplotlib
https://zhuanlan.zhihu.com/p/94331647
可能他也发表在别的网站,但作者就是他。以下代码是能够动态表示的,只是有乱码

#导入工具包
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import matplotlib.animation as animation
#from IPython.display import HTML
import random

df = pd.read_csv('china_provincedata.csv', usecols=['provinceName', 'provinceShortName', 'dateId', 'confirmedCount'])

fig, ax = plt.subplots(figsize=(15, 8))

colors = dict(zip(
    ['India','Europe','Asia','Latin America','Middle East','North America','Africa'],
    ['#adb0ff', '#ffb3ff', '#90d595', '#e48381', '#aafbff', '#f7bb5f', '#eafb50']
))
group_lk = df.set_index('provinceName')['provinceShortName'].to_dict()
def draw_barchart(current_day):
    dff = df.eq(current_day)].sort_values(by='confirmedCount', ascending=True).tail(10)
    ax.clear()
    #ax.barh(dff['provinceName'], dff['confirmedCount'], color=] for x in dff['provinceName']])
    ax.barh(dff['provinceShortName'],dff['confirmedCount'],color = for x in dff['provinceShortName']])
    dx = dff['confirmedCount'].max() / 200
    for i, (value, name) in enumerate(zip(dff['confirmedCount'], dff['provinceName'])):
      ax.text(value-dx, i,   name,         size=14, weight=600, ha='right', va='bottom')
      ax.text(value-dx, i-.25, group_lk, size=10, color='#444444', ha='right', va='baseline')
      ax.text(value+dx, i,   f'{value:,.0f}',size=14, ha='left',va='center')
    # ... 优化风格
    ax.text(1, 0.4, current_day, transform=ax.transAxes, color='#777777', size=46, ha='right', weight=800)
    ax.text(0, 1.06, 'Population (thousands)', transform=ax.transAxes, size=12, color='#777777')
    ax.xaxis.set_major_formatter(ticker.StrMethodFormatter('{x:,.0f}'))
    ax.xaxis.set_ticks_position('top')
    ax.tick_params(axis='x', colors='#777777', labelsize=12)
    ax.set_yticks([])
    ax.margins(0, 0.01)
    ax.grid(which='major', axis='x', linestyle='-')
    ax.set_axisbelow(True)
    ax.text(0, 1.12, 'The most populous cities in the world from 1500 to 2018',
            transform=ax.transAxes, size=24, weight=600, ha='left')
    ax.text(1, 0, 'by @pratapvardhan; credit @jburnmurdoch', transform=ax.transAxes, ha='right',
            color='#777777', bbox=dict(facecolor='white', alpha=0.8, edgecolor='white'))
    plt.box(False)
   
month_day=
def all_day(start,end):
    days = []
    cur_day = start
    while cur_day < end:
      mon = (cur_day//100) % 100
      if cur_day % 100 == month_day:
            cur_day = 20200000+(mon+1)*100+1
      else:
            cur_day += 1
      days.append(cur_day)
    return days
days = all_day(20200122,20200608)

def randomcolor():#颜色随机生成
    colorlist = ['1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']
    color =''
    for i in range(6):
      color += random.choice(colorlist)
    return '#'+ color

def get_colordict():
    area_list1 = set(df['provinceShortName'])
    color_list = []
    for i in range(len(area_list1)):
      str_1 = randomcolor()
      color_list.append(str_1)
      str_1 = randomcolor()
    area_list2 =

    color_dict = dict(zip(area_list2,color_list))
    return color_dict

draw_barchart(20200607)

animator = animation.FuncAnimation(fig, draw_barchart, frames=days)
#HTML(animator.to_jshtml())
plt.show()

朱宝恒 发表于 2020-6-20 18:12:46

java2python 发表于 2020-6-20 13:01
你的程序,应该是拷贝Bar Chart Race(条形竞赛图) in Python with Matplotlib
https://zhuanlan.zhihu.c ...

对,就是这个,但是比赛没有ipython库没法动态显示,我想解决的是这个问题

java2python 发表于 2020-6-20 18:34:08

朱宝恒 发表于 2020-6-20 18:12
对,就是这个,但是比赛没有ipython库没法动态显示,我想解决的是这个问题

我上边的程序没用到这个库啊,可以动态表示的啊,实际只表示条形图,不用matlab,用pygame也可以做到,只不过就是矩形嘛。你原先程序range(20200122,20200608),这个错了,走不动了,不会进入循环了。这个日期的列表需要手动生成。其他应该没问题的。

java2python 发表于 2020-6-20 18:50:24

不太好意思贴,gif文件太大,只能表示几天的,你这个区间有几个月:

896944660 发表于 2020-6-20 21:12:42

巧了,我也才参加省里的比赛,也用的是matplotlib,不过我还打算深入切PyQt开发,

朱宝恒 发表于 2020-6-20 21:48:37

Traceback (most recent call last):
File "E:\python\省赛材料\text3.py", line 96, in <module>
    draw_barchart(20200607)
File "E:\python\省赛材料\text3.py", line 37, in draw_barchart
    ax.text(value - dx, i - .25, group_lk, size=10, color='#444444', ha='right', va='baseline')
KeyError: '山东省'
我运行了一下你的代码,为什么山东省会出问题啊

java2python 发表于 2020-6-20 22:41:34

这个我也遇到了,怎么解决的,真的想不起来了,因为程序改的地方太多了:其实不算多,要改的地方A,B,C,D,E
结果A改成A+,B改成B+,C改成C+,如此组合起来,有时自己也晕了。真的想不起来了。

java2python 发表于 2020-6-20 23:17:30

别自己再一定要搞PKL了,泡菜,csv太低端?虽然这里毫无问题,其实没明白为何一定要excel线路,泡菜,怎么麻烦。或许是拿了别人的程序,觉得不加一点不好意思。怎么说呢,一开始应该先做能跑通的,看你好像,调试不咋过关,遇到问题,就求助了。不是说求助不行。而是毕竟这一来一回,哦特慢。。。
先搞一个能跑的,这个是最关键的,然后一步一步加,因为你加了三步,结果又不动了,就搞不清楚是哪一步出问题了。
调试很关键,为啥,毕竟不可能什么都求助,把程序弄成能跑是最基础的。
比如keyerror,可能是group_lk,找不到“山东省”的对应数据,实际我因为忘了。你最好能够有调试环境,光标行,用鼠标指上去,看看里面什么值,什么情况,一下子就明白了。
贴了个附件,这个应该是能跑的,如果你不加入自己的那些复杂东西的话。要加也是一步一步加,不是整体工程全搞完,然后一看不行,这有点扯谈。

朱宝恒 发表于 2020-6-21 19:39:53

谢谢你了,已经调试好了,没传上来,麻烦你了,用泡菜的原因其实是不让用pandas库,我原来用正则都写好了,又看到你的代码,然后我寻思着用二进制保存到本地然后一起上交,没有别的意思
谢谢你的帮助,其实我特别不愿意麻烦你们,我以后会继续努力的

朱宝恒 发表于 2020-6-21 19:41:43

哦错了,不是你这个,就是我原来拷贝的那个
页: [1]
查看完整版本: 高中生比赛求救急急急