经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Echarts » 查看文章
pyecharts的Tab和Legend布局详情
来源:jb51  时间:2022/3/7 11:13:31  对本文有异议

导言:

读者朋友有时候是不是和我有一样的困惑,用惯了matplotlibseaborn绘制各种各样的小图供自己观察的时候还算得心应手,但是一旦到了要持续的大批量绘制一些图表供非数据分析人员长久观察的时候又觉得吃力,那么有没有一款第三方python模块能够帮我们解决这种困惑呢?答案是肯定的,这就要推荐我们今天的主角——pyecharts。

pyecharts是百度开源的一款第三方绘图模块,结合的python语言的简易性和Echarts的强大绘图特性,可以用python对其调用,输出交互性好,精美乖巧且符合审美的图表,而且还可以轻松的集成到Flask,Django 等主流 Web 框架,方便自己和别人长久可持续观看。

一、布局设计思路

抛开数据谈布局简直有点天荒夜谈,数据长什么样决定了图表的花容月貌,熟稔自己手里的数据才能知自知彼绘制出优美的图表出来,首先看一下我们样例数据长什么样。

上图是我们的数据表,主要包含的字段有id, flight_date,cargo_type,cargo_weight以及cargo_rate, 其中id类似身份识别号,数量大约有400个左右,一个id就是一个主体,flight_date是记录id的时间,单位是日期,cargo_type表示主体承载的货物类别主要有"A;B", "C;D;E"和 "M"三大类,而cargo_weight和cargo_rate分别表示货物的重量和价格,这种类型的数据是不是像极了我们平时遇到的 各个门店里各类商品每天的销售数据。

知道了数据长什么样子后,我们就可以在草稿纸上画一画,比如我希望把cargo_weight和cargo_rate两者随着时间的变化而展现出的优美走位绘制出来,自然而然,flight_date就作为时间线索横梗在下面,cargo_weight和cargo_rate画在横坐标之上的两位舞者,为了区分,可以用柱状图绘制cargo_weight, 用曲线绘制cargo_rate,犹如蛟龙在群峰之间蜿蜒向前,为了区分刻画cargo_weight和cargo_rate两者之间不同数量级,我还需要引入主纵坐标和副纵坐标,用主坐标刻画cargo_weight的度量,用副坐标刻画cargo_rate的度量,有了这些基本要素之后,接下来问题的关键是怎么把id和cargo_type各放恰当的位置?这的确需要动些脑子,考虑到id和cargo_type两者的数量,可以把cargo_type作为Tab标签,而id作为Legend图例,可以让观察者每选定一个主体就能看到这个主体不同cargo_type的历史上cargo_weight和cargo_rate走势情况,而且还可以赋予每一个cargo_type一个主体配置。

二、操作实践

有了蓝图便胸有成竹,下面便是撰写代码实现的时候了

  1. import pandas as pd
  2. import pymysql
  3. import pyecharts
  4. from pyecharts import options as opts
  5. from pyecharts.charts import Bar, Grid, Line, Tab
  6. from pyecharts.globals import ThemeType
  7.  
  8. con = pymysql.Connect(host='000.00.0.00', user ='***', passwd='******', database='***')
  9. r_sql = "select id, cargo_type, flight_date, cargo_weight, cargo_rate from adm.adm_ifs_rate_order_price order by flight_date asc, voyage desc" #航班订单数据
  10. f_sql = "select concat(flight_no, '-', orac_3airport, '-', dstc_3airport) as id from ods.dm_flt_info where flight_date = date_sub(curdate(), INTERVAL -1 day) order by id asc" #次日航班计划
  11. raw_data = pd.read_sql(con = con, sql = r_sql) #读取运单原数据
  12. flight_id = pd.read_sql(con = con, sql = f_sql )['id'] #读取航班计划
  13. con.close() #关闭链接
  14.  
  15. flight_cargo = raw_data.query("id == @flight_id[0]") #筛选具体航班
  16.  
  17. cargo_type = ['A;B', 'C;D;E', 'M']
  18. cargo_ab = flight_cargo.query("cargo_type == @cargo_type[0] ")[["flight_date", ?"cargo_weight", ?"cargo_rate"]] #筛选某个货物类别
  19. cargo_cde = flight_cargo.query("cargo_type == @cargo_type[1] ")[["flight_date", ?"cargo_weight", ?"cargo_rate"]] #筛选某个货物类别
  20. cargo_m = flight_cargo.query("cargo_type == @cargo_type[2] ")[["flight_date", ?"cargo_weight", ?"cargo_rate"]] #筛选某个货物类别
  21.  
  22. def ab_() -> Grid:
  23. ? ? bar = (
  24. ? ? ? ? Bar()
  25. ? ? ? ? .add_xaxis(cargo_ab.flight_date.values.tolist())
  26. ? ? ? ? .add_yaxis("运量", cargo_ab.cargo_weight.values.tolist(), yaxis_index=0)
  27.  
  28. ? ? ? ? .set_series_opts(
  29. ? ? ? ? ? ? itemstyle_opts=opts.ItemStyleOpts(
  30. ? ? ? ? ? ? ? ? opacity=0.5,
  31. ? ? ? ? ? ? )
  32. ? ? ? ? ?)
  33. ? ? ? ? ?.extend_axis(
  34. ? ? ? ? ? ? yaxis=opts.AxisOpts(
  35. ? ? ? ? ? ? ? ? type_="value",
  36. ? ? ? ? ? ? ? ? name="运价",
  37. ? ? ? ? ? ? ? ? position="right",
  38. ? ? ? ? ? ? ? ? axisline_opts=opts.AxisLineOpts(
  39. ? ? ? ? ? ? ? ? ? ? linestyle_opts=opts.LineStyleOpts(color="#675bba")
  40. ? ? ? ? ? ? ? ? ),
  41. ? ? ? ? ? ? ? ? splitline_opts=opts.SplitLineOpts(
  42. ? ? ? ? ? ? ? ? ? ? is_show=True, linestyle_opts=opts.LineStyleOpts(opacity=0.5)
  43. ? ? ? ? ? ? ? ? ),
  44. ? ? ? ? ? ? )
  45. ? ? ? ? )
  46.  
  47. ? ? ? ? .set_global_opts(
  48. ? ? ? ? ? ? title_opts = opts.TitleOpts(title = flight_id[0]),
  49. ? ? ? ? ? ? yaxis_opts=opts.AxisOpts(name="运量"),
  50. ? ? ? ? ? ? datazoom_opts = opts.DataZoomOpts(),
  51.  
  52. ? ? ? ? )
  53. ? ? )
  54.  
  55.  
  56. ? ? line = (
  57. ? ? ? ? Line()
  58. ? ? ? ? .add_xaxis(cargo_ab.flight_date.values.tolist())
  59. ? ? ? ? .add_yaxis("运价", cargo_ab.cargo_rate.values.tolist(),yaxis_index=1
  60. ? ? ? ? )
  61. ? ? )
  62.  
  63. ? ? bar.overlap(line)
  64. ? ? return Grid().add(
  65. ? ? ? ? bar, opts.GridOpts(pos_left="5%", pos_right="20%"), is_control_axis_index=True
  66. ? ? )
  67.  
  68.  
  69. def cde_() -> Grid:
  70. ? ? bar = (
  71. ? ? ? ? Bar()
  72. ? ? ? ? .add_xaxis(cargo_cde.flight_date.values.tolist())
  73. ? ? ? ? .add_yaxis("运量", cargo_cde.cargo_weight.values.tolist(), yaxis_index=0)
  74.  
  75. ? ? ? ? .set_series_opts(
  76. ? ? ? ? ? ? itemstyle_opts=opts.ItemStyleOpts(
  77. ? ? ? ? ? ? ? ? opacity=0.5,
  78. ? ? ? ? ? ? )
  79. ? ? ? ? ?)
  80. ? ? ? ? ?.extend_axis(
  81. ? ? ? ? ? ? yaxis=opts.AxisOpts(
  82. ? ? ? ? ? ? ? ? type_="value",
  83. ? ? ? ? ? ? ? ? name="运价",
  84. ? ? ? ? ? ? ? ? position="right",
  85. ? ? ? ? ? ? ? ? axisline_opts=opts.AxisLineOpts(
  86. ? ? ? ? ? ? ? ? ? ? linestyle_opts=opts.LineStyleOpts(color="#675bba")
  87. ? ? ? ? ? ? ? ? ),
  88. ? ? ? ? ? ? ? ? splitline_opts=opts.SplitLineOpts(
  89. ? ? ? ? ? ? ? ? ? ? is_show=True, linestyle_opts=opts.LineStyleOpts(opacity=0.5)
  90. ? ? ? ? ? ? ? ? ),
  91. ? ? ? ? ? ? )
  92. ? ? ? ? )
  93.  
  94. ? ? ? ? .set_global_opts(
  95. ? ? ? ? ? ? title_opts=opts.TitleOpts(title=flight_id[0]),
  96. ? ? ? ? ? ? yaxis_opts=opts.AxisOpts(name="运量"),
  97. ? ? ? ? ? ? datazoom_opts=opts.DataZoomOpts(),
  98. ? ? ? ? )
  99. ? ? )
  100.  
  101.  
  102. ? ? line = (
  103. ? ? ? ? Line()
  104. ? ? ? ? .add_xaxis(cargo_cde.flight_date.values.tolist())
  105. ? ? ? ? .add_yaxis("运价", cargo_cde.cargo_rate.values.tolist(),yaxis_index=1
  106. ? ? ? ? )
  107. ? ? )
  108.  
  109. ? ? bar.overlap(line)
  110. ? ? return Grid().add(
  111. ? ? ? ? bar, opts.GridOpts(pos_left="5%", pos_right="20%"), is_control_axis_index=True
  112. ? ? )
  113.  
  114. def m_() -> Grid:
  115. ? ? bar = (
  116. ? ? ? ? Bar()
  117. ? ? ? ? .add_xaxis(cargo_m.flight_date.values.tolist())
  118. ? ? ? ? .add_yaxis("运量", cargo_m.cargo_weight.values.tolist(), yaxis_index=0)
  119.  
  120. ? ? ? ? .set_series_opts(
  121. ? ? ? ? ? ? itemstyle_opts=opts.ItemStyleOpts(
  122. ? ? ? ? ? ? ? ? opacity=0.5,
  123. ? ? ? ? ? ? )
  124. ? ? ? ? ?)
  125. ? ? ? ? ?.extend_axis(
  126. ? ? ? ? ? ? yaxis=opts.AxisOpts(
  127. ? ? ? ? ? ? ? ? type_="value",
  128. ? ? ? ? ? ? ? ? name="运价",
  129. ? ? ? ? ? ? ? ? position="right",
  130. ? ? ? ? ? ? ? ? axisline_opts=opts.AxisLineOpts(
  131. ? ? ? ? ? ? ? ? ? ? linestyle_opts=opts.LineStyleOpts(color="#675bba")
  132. ? ? ? ? ? ? ? ? ),
  133. ? ? ? ? ? ? ? ? splitline_opts=opts.SplitLineOpts(
  134. ? ? ? ? ? ? ? ? ? ? is_show=True, linestyle_opts=opts.LineStyleOpts(opacity=0.5)
  135. ? ? ? ? ? ? ? ? ),
  136. ? ? ? ? ? ? )
  137. ? ? ? ? )
  138.  
  139. ? ? ? ? .set_global_opts(
  140. ? ? ? ? ? ? title_opts=opts.TitleOpts(title=flight_id[6]),
  141. ? ? ? ? ? ? yaxis_opts=opts.AxisOpts(name="运量"),
  142. ? ? ? ? ? ? datazoom_opts=opts.DataZoomOpts(),
  143. ? ? ? ? )
  144. ? ? )
  145.  
  146.  
  147. ? ? line = (
  148. ? ? ? ? Line()
  149. ? ? ? ? .add_xaxis(cargo_m.flight_date.values.tolist())
  150. ? ? ? ? .add_yaxis("运价", cargo_m.cargo_rate.values.tolist(),yaxis_index=1
  151. ? ? ? ? )
  152. ? ? )
  153.  
  154. ? ? bar.overlap(line)
  155. ? ? return Grid().add(
  156. ? ? ? ? bar, opts.GridOpts(pos_left="5%", pos_right="20%"), is_control_axis_index=True
  157. ? ? )
  158.  
  159.  
  160. tab ?= Tab()
  161. tab.add(ab_(), "A;B")
  162. tab.add(cde_(), "C;D;E")
  163. tab.add(m_(), "M")
  164. tab.render_notebook()

下面结合效果图对代码做一下简单的解析,整个代码可以分3大块,第一块是连接数据库读取原数据并将数据一分为三,每一份数据为一个独立的货物类别;第二块是各用一个函数实现某类别货物cargo_weight和cargo_rate展示,而每一个函数作为Tab的参数进行调用,这样,每一个类别形成一个Tab,每一个Tab下面刚好有这个id的历史cargo_weight和cargo_rate走势情况,这样做样做的好处,用Tab就可以划分了cargo_type中"A;B", "C;D;E"和 "M"三个类别;最后调用render_notebook函数把所有Tab渲染出来。

结论:

效果图可以看到如果只要画一个id的各类货物的cargo_weight和cargo_rate走势的话,效果还是不错的,然而我们的id数目高达400个,上述方法很难奏效,我们希望让id去替换上图的运量和运价两个图例,形成id簇的图例,最好还可以对图例进行选择或者翻页

到此这篇关于pyecharts的Tab和Legend布局详情的文章就介绍到这了,更多相关Tab和Legend布局内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号