{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"在该 notebook,我们将介绍 xalpha 2020 引入的全新特性,及使用的典型范式,以期用户对 xalpha 的基本工作流有一个大致而全新的认识"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 基本设定"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"holdings.py is found and loaded within xalpha dir\n"
]
}
],
"source": [
"import xalpha as xa"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"我们总是推荐用 xa.meth 的方式来调用 xalpha 中的函数,\n",
"import xalpha from meth 强烈不建议使用,可能导致部分运行时动态调整功能和设定失效"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"xa.set_backend(backend=\"csv\", path=\"../../../lof/data\", precached=\"20170101\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"通过上述命令,我们设定了 xalpha 的全局本地缓存,可以将利用到的金融数据日线全部缓存到本地文件夹 path 中,并以 csv 文件的形式存在。\n",
"该缓存也支持数据库后端,backend=\"sql\".\n",
"同时 precached 命令告诉缓存引擎,无论抓取的数据需要多少,都至少先将 20170101 至今的数据爬取并缓存到本地。"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"import logging\n",
"\n",
"logger = logging.getLogger(\"xalpha\")\n",
"logger.setLevel(logging.DEBUG)\n",
"ch = logging.StreamHandler()\n",
"ch.setLevel(logging.DEBUG)\n",
"logger.addHandler(ch)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"我们接下来设定 xalpha 的日志输出,上述设定表示打印 xalpha 所有 DEBUG 级别以上的日志,同时打印到 jupyter notebook 里,\n",
"这些内容详细记录了网络连接等 debug 信息。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 使用日线和实时获取器"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" date | \n",
" close | \n",
"
\n",
" \n",
" \n",
" \n",
" 487 | \n",
" 2019-01-02 | \n",
" 6.8482 | \n",
"
\n",
" \n",
" 488 | \n",
" 2019-01-03 | \n",
" 6.8631 | \n",
"
\n",
" \n",
" 489 | \n",
" 2019-01-04 | \n",
" 6.8586 | \n",
"
\n",
" \n",
" 490 | \n",
" 2019-01-07 | \n",
" 6.8517 | \n",
"
\n",
" \n",
" 491 | \n",
" 2019-01-08 | \n",
" 6.8402 | \n",
"
\n",
" \n",
" 492 | \n",
" 2019-01-09 | \n",
" 6.8526 | \n",
"
\n",
" \n",
" 493 | \n",
" 2019-01-10 | \n",
" 6.8160 | \n",
"
\n",
" \n",
" 494 | \n",
" 2019-01-11 | \n",
" 6.7909 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" date close\n",
"487 2019-01-02 6.8482\n",
"488 2019-01-03 6.8631\n",
"489 2019-01-04 6.8586\n",
"490 2019-01-07 6.8517\n",
"491 2019-01-08 6.8402\n",
"492 2019-01-09 6.8526\n",
"493 2019-01-10 6.8160\n",
"494 2019-01-11 6.7909"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 我们可以通过 get_daily 来获取几乎一切内容的日线信息\n",
"# 下边并未有 log,显示我们的缓存后端本来就有该文件\n",
"xa.get_daily(\"USD/CNY\", start=\"20190101\", end=\"20190113\")"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Fetching url: http://www.chinamoney.com.cn/ags/ms/cm-u-bk-ccpr/CcprHisNew?startDate=2019-04-10&endDate=2020-04-04¤cy=SGD/CNY&pageNum=1&pageSize=300 . Inside function `get_rmb`\n",
"Fetching url: http://www.chinamoney.com.cn/ags/ms/cm-u-bk-ccpr/CcprHisNew?startDate=2018-04-14&endDate=2019-04-09¤cy=SGD/CNY&pageNum=1&pageSize=300 . Inside function `get_rmb`\n",
"Fetching url: http://www.chinamoney.com.cn/ags/ms/cm-u-bk-ccpr/CcprHisNew?startDate=2017-04-18&endDate=2018-04-13¤cy=SGD/CNY&pageNum=1&pageSize=300 . Inside function `get_rmb`\n",
"Fetching url: http://www.chinamoney.com.cn/ags/ms/cm-u-bk-ccpr/CcprHisNew?startDate=2017-01-01&endDate=2017-04-17¤cy=SGD/CNY&pageNum=1&pageSize=300 . Inside function `get_rmb`\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" date | \n",
" close | \n",
"
\n",
" \n",
" \n",
" \n",
" 24 | \n",
" 2020-03-02 | \n",
" 5.0129 | \n",
"
\n",
" \n",
" 23 | \n",
" 2020-03-03 | \n",
" 5.0039 | \n",
"
\n",
" \n",
" 22 | \n",
" 2020-03-04 | \n",
" 5.0087 | \n",
"
\n",
" \n",
" 21 | \n",
" 2020-03-05 | \n",
" 5.0091 | \n",
"
\n",
" \n",
" 20 | \n",
" 2020-03-06 | \n",
" 5.0099 | \n",
"
\n",
" \n",
" 19 | \n",
" 2020-03-09 | \n",
" 5.0254 | \n",
"
\n",
" \n",
" 18 | \n",
" 2020-03-10 | \n",
" 5.0132 | \n",
"
\n",
" \n",
" 17 | \n",
" 2020-03-11 | \n",
" 5.0027 | \n",
"
\n",
" \n",
" 16 | \n",
" 2020-03-12 | \n",
" 4.9876 | \n",
"
\n",
" \n",
" 15 | \n",
" 2020-03-13 | \n",
" 4.9691 | \n",
"
\n",
" \n",
" 14 | \n",
" 2020-03-16 | \n",
" 4.9551 | \n",
"
\n",
" \n",
" 13 | \n",
" 2020-03-17 | \n",
" 4.9320 | \n",
"
\n",
" \n",
" 12 | \n",
" 2020-03-18 | \n",
" 4.9200 | \n",
"
\n",
" \n",
" 11 | \n",
" 2020-03-19 | \n",
" 4.8917 | \n",
"
\n",
" \n",
" 10 | \n",
" 2020-03-20 | \n",
" 4.8975 | \n",
"
\n",
" \n",
" 9 | \n",
" 2020-03-23 | \n",
" 4.8775 | \n",
"
\n",
" \n",
" 8 | \n",
" 2020-03-24 | \n",
" 4.8720 | \n",
"
\n",
" \n",
" 7 | \n",
" 2020-03-25 | \n",
" 4.8881 | \n",
"
\n",
" \n",
" 6 | \n",
" 2020-03-26 | \n",
" 4.8827 | \n",
"
\n",
" \n",
" 5 | \n",
" 2020-03-27 | \n",
" 4.9231 | \n",
"
\n",
" \n",
" 4 | \n",
" 2020-03-30 | \n",
" 4.9329 | \n",
"
\n",
" \n",
" 3 | \n",
" 2020-03-31 | \n",
" 4.9724 | \n",
"
\n",
" \n",
" 2 | \n",
" 2020-04-01 | \n",
" 4.9792 | \n",
"
\n",
" \n",
" 1 | \n",
" 2020-04-02 | \n",
" 4.9465 | \n",
"
\n",
" \n",
" 0 | \n",
" 2020-04-03 | \n",
" 4.9685 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" date close\n",
"24 2020-03-02 5.0129\n",
"23 2020-03-03 5.0039\n",
"22 2020-03-04 5.0087\n",
"21 2020-03-05 5.0091\n",
"20 2020-03-06 5.0099\n",
"19 2020-03-09 5.0254\n",
"18 2020-03-10 5.0132\n",
"17 2020-03-11 5.0027\n",
"16 2020-03-12 4.9876\n",
"15 2020-03-13 4.9691\n",
"14 2020-03-16 4.9551\n",
"13 2020-03-17 4.9320\n",
"12 2020-03-18 4.9200\n",
"11 2020-03-19 4.8917\n",
"10 2020-03-20 4.8975\n",
"9 2020-03-23 4.8775\n",
"8 2020-03-24 4.8720\n",
"7 2020-03-25 4.8881\n",
"6 2020-03-26 4.8827\n",
"5 2020-03-27 4.9231\n",
"4 2020-03-30 4.9329\n",
"3 2020-03-31 4.9724\n",
"2 2020-04-01 4.9792\n",
"1 2020-04-02 4.9465\n",
"0 2020-04-03 4.9685"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 对与人民币美元中间价的获取,log 显示了更新,和爬取到 20170101 的过程\n",
"xa.get_daily(\"SGD/CNY\", start=\"20200301\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"对于彭博数据的爬取,可能需要设定网络代理, xalpha 支持 http 和 socks 代理,并可以运行时随时设定随时取消。"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Using proxy socks5://127.0.0.1:1080\n",
"Fetching url: https://www.bloomberg.com/markets2/api/history/ZGLD:SW/PX_LAST?timeframe=1_MONTH&period=daily&volumePeriod=daily . Inside function `get_historical_frombb`\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" date | \n",
" close | \n",
"
\n",
" \n",
" \n",
" \n",
" 1245 | \n",
" 2020-03-16 | \n",
" 434.75 | \n",
"
\n",
" \n",
" 1246 | \n",
" 2020-03-17 | \n",
" 449.35 | \n",
"
\n",
" \n",
" 1247 | \n",
" 2020-03-18 | \n",
" 440.00 | \n",
"
\n",
" \n",
" 1248 | \n",
" 2020-03-19 | \n",
" 441.45 | \n",
"
\n",
" \n",
" 1249 | \n",
" 2020-03-20 | \n",
" 444.55 | \n",
"
\n",
" \n",
" 1250 | \n",
" 2020-03-23 | \n",
" 463.00 | \n",
"
\n",
" \n",
" 1251 | \n",
" 2020-03-24 | \n",
" 487.90 | \n",
"
\n",
" \n",
" 1252 | \n",
" 2020-03-25 | \n",
" 483.75 | \n",
"
\n",
" \n",
" 1253 | \n",
" 2020-03-26 | \n",
" 481.80 | \n",
"
\n",
" \n",
" 1254 | \n",
" 2020-03-27 | \n",
" 474.50 | \n",
"
\n",
" \n",
" 1255 | \n",
" 2020-03-30 | \n",
" 474.85 | \n",
"
\n",
" \n",
" 1256 | \n",
" 2020-03-31 | \n",
" 474.00 | \n",
"
\n",
" \n",
" 1257 | \n",
" 2020-04-01 | \n",
" 468.10 | \n",
"
\n",
" \n",
" 1258 | \n",
" 2020-04-02 | \n",
" 476.75 | \n",
"
\n",
" \n",
" 1259 | \n",
" 2020-04-03 | \n",
" 481.00 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" date close\n",
"1245 2020-03-16 434.75\n",
"1246 2020-03-17 449.35\n",
"1247 2020-03-18 440.00\n",
"1248 2020-03-19 441.45\n",
"1249 2020-03-20 444.55\n",
"1250 2020-03-23 463.00\n",
"1251 2020-03-24 487.90\n",
"1252 2020-03-25 483.75\n",
"1253 2020-03-26 481.80\n",
"1254 2020-03-27 474.50\n",
"1255 2020-03-30 474.85\n",
"1256 2020-03-31 474.00\n",
"1257 2020-04-01 468.10\n",
"1258 2020-04-02 476.75\n",
"1259 2020-04-03 481.00"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"xa.set_proxy(\"socks5://127.0.0.1:1080\") # 设置本地 socks 代理\n",
"df = xa.get_daily(\"BB-ZGLD:SW\", prev=20) # 抓取数据\n",
"xa.set_proxy() # 取消代理\n",
"df"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" date | \n",
" open | \n",
" close | \n",
" high | \n",
" low | \n",
" percent | \n",
"
\n",
" \n",
" \n",
" \n",
" 3158 | \n",
" 2020-03-25 | \n",
" 24.37 | \n",
" 24.49 | \n",
" 25.24 | \n",
" 22.91 | \n",
" 2.00% | \n",
"
\n",
" \n",
" 3159 | \n",
" 2020-03-26 | \n",
" 24.25 | \n",
" 22.60 | \n",
" 24.65 | \n",
" 22.38 | \n",
" -7.72% | \n",
"
\n",
" \n",
" 3160 | \n",
" 2020-03-27 | \n",
" 23.29 | \n",
" 21.51 | \n",
" 23.44 | \n",
" 20.88 | \n",
" -4.82% | \n",
"
\n",
" \n",
" 3161 | \n",
" 2020-03-30 | \n",
" 20.93 | \n",
" 20.09 | \n",
" 20.93 | \n",
" 19.27 | \n",
" -6.60% | \n",
"
\n",
" \n",
" 3162 | \n",
" 2020-03-31 | \n",
" 20.23 | \n",
" 20.48 | \n",
" 21.89 | \n",
" 20.01 | \n",
" 1.94% | \n",
"
\n",
" \n",
" 3163 | \n",
" 2020-04-01 | \n",
" 20.10 | \n",
" 20.31 | \n",
" 21.55 | \n",
" 19.90 | \n",
" -0.83% | \n",
"
\n",
" \n",
" 3164 | \n",
" 2020-04-02 | \n",
" 21.22 | \n",
" 25.32 | \n",
" 27.39 | \n",
" 20.76 | \n",
" 24.67% | \n",
"
\n",
" \n",
" 3165 | \n",
" 2020-04-03 | \n",
" 24.71 | \n",
" 24.05 | \n",
" 24.71 | \n",
" 23.52 | \n",
" -5.02% | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" date open close high low percent\n",
"3158 2020-03-25 24.37 24.49 25.24 22.91 2.00%\n",
"3159 2020-03-26 24.25 22.60 24.65 22.38 -7.72%\n",
"3160 2020-03-27 23.29 21.51 23.44 20.88 -4.82%\n",
"3161 2020-03-30 20.93 20.09 20.93 19.27 -6.60%\n",
"3162 2020-03-31 20.23 20.48 21.89 20.01 1.94%\n",
"3163 2020-04-01 20.10 20.31 21.55 19.90 -0.83%\n",
"3164 2020-04-02 21.22 25.32 27.39 20.76 24.67%\n",
"3165 2020-04-03 24.71 24.05 24.71 23.52 -5.02%"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 获取英为数据\n",
"xa.get_daily(\"commodities/crude-oil\", prev=10)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" date | \n",
" open | \n",
" close | \n",
" high | \n",
" low | \n",
"
\n",
" \n",
" \n",
" \n",
" 812 | \n",
" 2020-03-25 | \n",
" 24.37 | \n",
" 24.31 | \n",
" 25.24 | \n",
" 22.91 | \n",
"
\n",
" \n",
" 813 | \n",
" 2020-03-26 | \n",
" 24.25 | \n",
" 23.18 | \n",
" 24.65 | \n",
" 22.38 | \n",
"
\n",
" \n",
" 814 | \n",
" 2020-03-27 | \n",
" 23.29 | \n",
" 21.84 | \n",
" 23.44 | \n",
" 20.88 | \n",
"
\n",
" \n",
" 815 | \n",
" 2020-03-30 | \n",
" 20.93 | \n",
" 20.28 | \n",
" 20.93 | \n",
" 19.27 | \n",
"
\n",
" \n",
" 816 | \n",
" 2020-03-31 | \n",
" 20.23 | \n",
" 20.10 | \n",
" 21.89 | \n",
" 20.01 | \n",
"
\n",
" \n",
" 817 | \n",
" 2020-04-01 | \n",
" 20.10 | \n",
" 21.20 | \n",
" 21.55 | \n",
" 19.90 | \n",
"
\n",
" \n",
" 818 | \n",
" 2020-04-02 | \n",
" 21.22 | \n",
" 24.75 | \n",
" 27.39 | \n",
" 20.76 | \n",
"
\n",
" \n",
" 819 | \n",
" 2020-04-03 | \n",
" 24.81 | \n",
" 24.88 | \n",
" 25.21 | \n",
" 23.52 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" date open close high low\n",
"812 2020-03-25 24.37 24.31 25.24 22.91\n",
"813 2020-03-26 24.25 23.18 24.65 22.38\n",
"814 2020-03-27 23.29 21.84 23.44 20.88\n",
"815 2020-03-30 20.93 20.28 20.93 19.27\n",
"816 2020-03-31 20.23 20.10 21.89 20.01\n",
"817 2020-04-01 20.10 21.20 21.55 19.90\n",
"818 2020-04-02 21.22 24.75 27.39 20.76\n",
"819 2020-04-03 24.81 24.88 25.21 23.52"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 获取 FT 数据\n",
"xa.get_daily(\"FTC-WTI+Crude+Oil\", prev=10)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Fetching url: https://us.spindices.com/idsexport/file.xls?selectedModule=PerformanceGraphView&selectedSubModule=Graph&yearFlag=oneYearFlag&indexId=5475707 . Inside function `get_historical_fromsp`\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" date | \n",
" close | \n",
"
\n",
" \n",
" \n",
" \n",
" 780 | \n",
" 2020-03-25 | \n",
" 896.87 | \n",
"
\n",
" \n",
" 781 | \n",
" 2020-03-26 | \n",
" 931.77 | \n",
"
\n",
" \n",
" 782 | \n",
" 2020-03-27 | \n",
" 875.53 | \n",
"
\n",
" \n",
" 783 | \n",
" 2020-03-30 | \n",
" 887.21 | \n",
"
\n",
" \n",
" 784 | \n",
" 2020-03-31 | \n",
" 928.01 | \n",
"
\n",
" \n",
" 785 | \n",
" 2020-04-01 | \n",
" 900.94 | \n",
"
\n",
" \n",
" 786 | \n",
" 2020-04-02 | \n",
" 962.12 | \n",
"
\n",
" \n",
" 787 | \n",
" 2020-04-03 | \n",
" 949.04 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" date close\n",
"780 2020-03-25 896.87\n",
"781 2020-03-26 931.77\n",
"782 2020-03-27 875.53\n",
"783 2020-03-30 887.21\n",
"784 2020-03-31 928.01\n",
"785 2020-04-01 900.94\n",
"786 2020-04-02 962.12\n",
"787 2020-04-03 949.04"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 获取标普各种指数数据\n",
"xa.get_daily(\"SP5475707.2\", prev=10)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Fetching url: https://query1.finance.yahoo.com/v8/finance/chart/CSGOLD.SW?region=US&lang=en-US&includePrePost=false&interval=1d&range=5y&corsDomain=finance.yahoo.com&.tsrc=finance . Inside function `get_historical_fromyh`\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" date | \n",
" close | \n",
" open | \n",
" high | \n",
" low | \n",
"
\n",
" \n",
" \n",
" \n",
" 1250 | \n",
" 2020-03-27 | \n",
" 156.559998 | \n",
" 155.820007 | \n",
" 158.320007 | \n",
" 155.240005 | \n",
"
\n",
" \n",
" 1251 | \n",
" 2020-03-30 | \n",
" 157.360001 | \n",
" 158.059998 | \n",
" 158.059998 | \n",
" 156.259995 | \n",
"
\n",
" \n",
" 1252 | \n",
" 2020-03-31 | \n",
" 156.160004 | \n",
" 156.619995 | \n",
" 156.679993 | \n",
" 153.899994 | \n",
"
\n",
" \n",
" 1253 | \n",
" 2020-04-01 | \n",
" 154.080002 | \n",
" 153.720001 | \n",
" 155.679993 | \n",
" 152.619995 | \n",
"
\n",
" \n",
" 1254 | \n",
" 2020-04-02 | \n",
" 156.240005 | \n",
" 154.300003 | \n",
" 157.360001 | \n",
" 153.660004 | \n",
"
\n",
" \n",
" 1255 | \n",
" 2020-04-03 | \n",
" 156.679993 | \n",
" 155.800003 | \n",
" 157.899994 | \n",
" 155.399994 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" date close open high low\n",
"1250 2020-03-27 156.559998 155.820007 158.320007 155.240005\n",
"1251 2020-03-30 157.360001 158.059998 158.059998 156.259995\n",
"1252 2020-03-31 156.160004 156.619995 156.679993 153.899994\n",
"1253 2020-04-01 154.080002 153.720001 155.679993 152.619995\n",
"1254 2020-04-02 156.240005 154.300003 157.360001 153.660004\n",
"1255 2020-04-03 156.679993 155.800003 157.899994 155.399994"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 获取雅虎数据\n",
"xa.get_daily(\"YH-CSGOLD.SW\", prev=8)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" date | \n",
" open | \n",
" close | \n",
" high | \n",
" low | \n",
" percent | \n",
"
\n",
" \n",
" \n",
" \n",
" 218 | \n",
" 2020-03-30 | \n",
" 26.50 | \n",
" 25.60 | \n",
" 26.80 | \n",
" 25.02 | \n",
" -0.12 | \n",
"
\n",
" \n",
" 219 | \n",
" 2020-03-31 | \n",
" 26.36 | \n",
" 27.19 | \n",
" 29.53 | \n",
" 26.01 | \n",
" 6.21 | \n",
"
\n",
" \n",
" 220 | \n",
" 2020-04-01 | \n",
" 26.14 | \n",
" 26.20 | \n",
" 26.60 | \n",
" 25.02 | \n",
" -3.64 | \n",
"
\n",
" \n",
" 221 | \n",
" 2020-04-02 | \n",
" 4.91 | \n",
" 6.40 | \n",
" 10.58 | \n",
" 4.90 | \n",
" -75.57 | \n",
"
\n",
" \n",
" 222 | \n",
" 2020-04-03 | \n",
" 7.05 | \n",
" 5.38 | \n",
" 7.35 | \n",
" 5.28 | \n",
" -15.94 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" date open close high low percent\n",
"218 2020-03-30 26.50 25.60 26.80 25.02 -0.12\n",
"219 2020-03-31 26.36 27.19 29.53 26.01 6.21\n",
"220 2020-04-01 26.14 26.20 26.60 25.02 -3.64\n",
"221 2020-04-02 4.91 6.40 10.58 4.90 -75.57\n",
"222 2020-04-03 7.05 5.38 7.35 5.28 -15.94"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 获取美股数据\n",
"xa.get_daily(\"LK\", prev=5)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Fetching url: https://stock.xueqiu.com/v5/stock/chart/kline.json?symbol=SH600000&begin=1586069190611&period=day&type=before&count=-1190 . Inside function `get_history`\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" date | \n",
" open | \n",
" close | \n",
" high | \n",
" low | \n",
" percent | \n",
"
\n",
" \n",
" \n",
" \n",
" 1185 | \n",
" 2020-03-30 | \n",
" 10.18 | \n",
" 10.28 | \n",
" 10.28 | \n",
" 10.11 | \n",
" 0.39 | \n",
"
\n",
" \n",
" 1186 | \n",
" 2020-03-31 | \n",
" 10.30 | \n",
" 10.15 | \n",
" 10.36 | \n",
" 10.13 | \n",
" -1.26 | \n",
"
\n",
" \n",
" 1187 | \n",
" 2020-04-01 | \n",
" 10.11 | \n",
" 10.09 | \n",
" 10.26 | \n",
" 10.09 | \n",
" -0.59 | \n",
"
\n",
" \n",
" 1188 | \n",
" 2020-04-02 | \n",
" 10.09 | \n",
" 10.20 | \n",
" 10.20 | \n",
" 10.07 | \n",
" 1.09 | \n",
"
\n",
" \n",
" 1189 | \n",
" 2020-04-03 | \n",
" 10.13 | \n",
" 10.15 | \n",
" 10.21 | \n",
" 10.12 | \n",
" -0.49 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" date open close high low percent\n",
"1185 2020-03-30 10.18 10.28 10.28 10.11 0.39\n",
"1186 2020-03-31 10.30 10.15 10.36 10.13 -1.26\n",
"1187 2020-04-01 10.11 10.09 10.26 10.09 -0.59\n",
"1188 2020-04-02 10.09 10.20 10.20 10.07 1.09\n",
"1189 2020-04-03 10.13 10.15 10.21 10.12 -0.49"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 获取 A 股数据\n",
"xa.get_daily(\"SH600000\", prev=5)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Fetching url: https://stock.xueqiu.com/v5/stock/chart/kline.json?symbol=00700&begin=1586069217747&period=day&type=before&count=-9 . Inside function `get_history`\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" date | \n",
" open | \n",
" close | \n",
" high | \n",
" low | \n",
" percent | \n",
"
\n",
" \n",
" \n",
" \n",
" 1181 | \n",
" 2020-03-30 | \n",
" 371.8 | \n",
" 376.6 | \n",
" 380.0 | \n",
" 371.6 | \n",
" -1.52 | \n",
"
\n",
" \n",
" 1182 | \n",
" 2020-03-31 | \n",
" 385.2 | \n",
" 380.2 | \n",
" 386.0 | \n",
" 370.8 | \n",
" 0.96 | \n",
"
\n",
" \n",
" 1183 | \n",
" 2020-04-01 | \n",
" 383.6 | \n",
" 374.4 | \n",
" 383.6 | \n",
" 372.4 | \n",
" -1.53 | \n",
"
\n",
" \n",
" 1184 | \n",
" 2020-04-02 | \n",
" 370.0 | \n",
" 379.8 | \n",
" 379.8 | \n",
" 369.6 | \n",
" 1.44 | \n",
"
\n",
" \n",
" 1185 | \n",
" 2020-04-03 | \n",
" 372.0 | \n",
" 376.4 | \n",
" 376.4 | \n",
" 372.0 | \n",
" -0.90 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" date open close high low percent\n",
"1181 2020-03-30 371.8 376.6 380.0 371.6 -1.52\n",
"1182 2020-03-31 385.2 380.2 386.0 370.8 0.96\n",
"1183 2020-04-01 383.6 374.4 383.6 372.4 -1.53\n",
"1184 2020-04-02 370.0 379.8 379.8 369.6 1.44\n",
"1185 2020-04-03 372.0 376.4 376.4 372.0 -0.90"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 获取港股数据\n",
"xa.get_daily(\"HK00700\", prev=5)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Fetching url: http://fund.eastmoney.com/pingzhongdata/501018.js . Inside function `_basic_init`\n",
"Fetching url: http://fund.eastmoney.com/f10/jjfl_501018.html . Inside function `_feepreprocess`\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"no saved copy of 501018\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" date | \n",
" close | \n",
"
\n",
" \n",
" \n",
" \n",
" 916 | \n",
" 2020-03-30 | \n",
" 0.5183 | \n",
"
\n",
" \n",
" 917 | \n",
" 2020-03-31 | \n",
" 0.5241 | \n",
"
\n",
" \n",
" 918 | \n",
" 2020-04-01 | \n",
" 0.5142 | \n",
"
\n",
" \n",
" 919 | \n",
" 2020-04-02 | \n",
" 0.5723 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" date close\n",
"916 2020-03-30 0.5183\n",
"917 2020-03-31 0.5241\n",
"918 2020-04-01 0.5142\n",
"919 2020-04-02 0.5723"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 获取基金数据\n",
"xa.get_daily(\"F501018\", prev=5)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"我们也可以通过 get_rt 获取实时数据,通过 get_bar 获取分钟线小时线等数据,以下是一些例子"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'currency': 'USD',\n",
" 'current': 51.19,\n",
" 'current_ext': 51.39,\n",
" 'floatshare': None,\n",
" 'market': 'US',\n",
" 'name': '拼多多',\n",
" 'percent': 3.27,\n",
" 'time': '2020-04-28 04:00:00',\n",
" 'totshare': 1197626247,\n",
" 'volume': 4717569}"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"xa.get_rt(\"PDD\")"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'currency': 'CNY',\n",
" 'current': 0.717,\n",
" 'current_ext': None,\n",
" 'floatshare': None,\n",
" 'market': 'CN',\n",
" 'name': '南方原油LOF',\n",
" 'percent': -1.38,\n",
" 'time': '2020-04-28 09:30:04',\n",
" 'totshare': 3180963285,\n",
" 'volume': 7808665}"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"xa.get_rt(\"SH501018\")\n",
"# 请注意第二次请求已经不需要去要雪球 token 了,因为已缓存"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Fetching url: https://markets.ft.com/data/indices/tearsheet/summary?s=INX:IOM . Inside function `get_rt_from_ft`\n"
]
},
{
"data": {
"text/plain": [
"{'currency': 'USD',\n",
" 'current': 2488.65,\n",
" 'current_ext': None,\n",
" 'market': None,\n",
" 'name': 'S&P 500 INDEX',\n",
" 'percent': -1.51}"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"xa.get_rt(\"FT-INX:IOM\")\n",
"# 请注意 FT 的实时数据存在延迟!"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Fetching url: https://cnappapi.investing.com/currencies/usd-cnh . Inside function `get_cninvesting_rt`\n"
]
},
{
"data": {
"text/plain": [
"{'currency': None,\n",
" 'current': 7.1119,\n",
" 'current_ext': None,\n",
" 'market': None,\n",
" 'name': 'USD/CNH - 美元 离岸人民币',\n",
" 'percent': 0.26}"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"xa.get_rt(\"INA-currencies/usd-cnh\")\n",
"# 从 app 源获取英为实时数据"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Fetching url: https://xueqiu.com . Inside function `get_token`\n",
"Fetching url: https://stock.xueqiu.com/v5/stock/quote.json?symbol=SH600000&extend=detail . Inside function `get_xueqiu_rt`\n",
"Fetching url: https://hq.sinajs.cn/list=sh600000 . Inside function `get_rt_from_sina`\n"
]
},
{
"data": {
"text/plain": [
"{'currency': 'CNY',\n",
" 'current': 10.15,\n",
" 'current_ext': None,\n",
" 'market': 'CN',\n",
" 'name': '浦发银行',\n",
" 'percent': -0.49}"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"xa.get_rt(\"SH600000\", double_check=True)\n",
"# 获取 A 股数据,并经过新浪源的双重校验"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Fetching url: https://cn.investing.com/indices/germany-30 . Inside function `get_investing_id`\n",
"Fetching url: https://cn.investing.com/common/modules/js_instrument_chart/api/data.php?pair_id=172&pair_id_for_news=172&chart_type=area&pair_interval=3600&candle_count=24&events=yes&volume_series=yes&period= . Inside function `get_bar_frominvesting`\n"
]
},
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" date | \n",
" close | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" 2020-04-01 18:00:00 | \n",
" 9583.50 | \n",
"
\n",
" \n",
" 1 | \n",
" 2020-04-01 19:00:00 | \n",
" 9551.50 | \n",
"
\n",
" \n",
" 2 | \n",
" 2020-04-01 20:00:00 | \n",
" 9533.00 | \n",
"
\n",
" \n",
" 3 | \n",
" 2020-04-01 21:00:00 | \n",
" 9559.75 | \n",
"
\n",
" \n",
" 4 | \n",
" 2020-04-01 22:00:00 | \n",
" 9586.75 | \n",
"
\n",
" \n",
" 5 | \n",
" 2020-04-01 23:00:00 | \n",
" 9539.50 | \n",
"
\n",
" \n",
" 6 | \n",
" 2020-04-02 15:00:00 | \n",
" 9542.25 | \n",
"
\n",
" \n",
" 7 | \n",
" 2020-04-02 16:00:00 | \n",
" 9565.75 | \n",
"
\n",
" \n",
" 8 | \n",
" 2020-04-02 17:00:00 | \n",
" 9548.75 | \n",
"
\n",
" \n",
" 9 | \n",
" 2020-04-02 18:00:00 | \n",
" 9594.25 | \n",
"
\n",
" \n",
" 10 | \n",
" 2020-04-02 19:00:00 | \n",
" 9580.50 | \n",
"
\n",
" \n",
" 11 | \n",
" 2020-04-02 20:00:00 | \n",
" 9433.00 | \n",
"
\n",
" \n",
" 12 | \n",
" 2020-04-02 21:00:00 | \n",
" 9451.50 | \n",
"
\n",
" \n",
" 13 | \n",
" 2020-04-02 22:00:00 | \n",
" 9613.75 | \n",
"
\n",
" \n",
" 14 | \n",
" 2020-04-02 23:00:00 | \n",
" 9569.00 | \n",
"
\n",
" \n",
" 15 | \n",
" 2020-04-03 15:00:00 | \n",
" 9534.75 | \n",
"
\n",
" \n",
" 16 | \n",
" 2020-04-03 16:00:00 | \n",
" 9529.75 | \n",
"
\n",
" \n",
" 17 | \n",
" 2020-04-03 17:00:00 | \n",
" 9527.00 | \n",
"
\n",
" \n",
" 18 | \n",
" 2020-04-03 18:00:00 | \n",
" 9535.25 | \n",
"
\n",
" \n",
" 19 | \n",
" 2020-04-03 19:00:00 | \n",
" 9611.00 | \n",
"
\n",
" \n",
" 20 | \n",
" 2020-04-03 20:00:00 | \n",
" 9569.75 | \n",
"
\n",
" \n",
" 21 | \n",
" 2020-04-03 21:00:00 | \n",
" 9558.75 | \n",
"
\n",
" \n",
" 22 | \n",
" 2020-04-03 22:00:00 | \n",
" 9547.25 | \n",
"
\n",
" \n",
" 23 | \n",
" 2020-04-03 23:00:00 | \n",
" 9525.77 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" date close\n",
"0 2020-04-01 18:00:00 9583.50\n",
"1 2020-04-01 19:00:00 9551.50\n",
"2 2020-04-01 20:00:00 9533.00\n",
"3 2020-04-01 21:00:00 9559.75\n",
"4 2020-04-01 22:00:00 9586.75\n",
"5 2020-04-01 23:00:00 9539.50\n",
"6 2020-04-02 15:00:00 9542.25\n",
"7 2020-04-02 16:00:00 9565.75\n",
"8 2020-04-02 17:00:00 9548.75\n",
"9 2020-04-02 18:00:00 9594.25\n",
"10 2020-04-02 19:00:00 9580.50\n",
"11 2020-04-02 20:00:00 9433.00\n",
"12 2020-04-02 21:00:00 9451.50\n",
"13 2020-04-02 22:00:00 9613.75\n",
"14 2020-04-02 23:00:00 9569.00\n",
"15 2020-04-03 15:00:00 9534.75\n",
"16 2020-04-03 16:00:00 9529.75\n",
"17 2020-04-03 17:00:00 9527.00\n",
"18 2020-04-03 18:00:00 9535.25\n",
"19 2020-04-03 19:00:00 9611.00\n",
"20 2020-04-03 20:00:00 9569.75\n",
"21 2020-04-03 21:00:00 9558.75\n",
"22 2020-04-03 22:00:00 9547.25\n",
"23 2020-04-03 23:00:00 9525.77"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"xa.get_bar(\"indices/germany-30\", interval=3600)\n",
"# 获取小时线数据"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"下面简单演示对于承载数据的 pd.DataFrame 的简单处理和可视化"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"7.0995"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df = xa.get_daily(\"USD/CNY\", prev=20)\n",
"df[df[\"date\"] == \"2020-04-02\"].iloc[0][\"close\"]"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support.' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" if (mpl.ratio != 1) {\n",
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
" }\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" fig.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '');\n",
" var titletext = $(\n",
" '');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var backingStore = this.context.backingStorePixelRatio ||\n",
"\tthis.context.webkitBackingStorePixelRatio ||\n",
"\tthis.context.mozBackingStorePixelRatio ||\n",
"\tthis.context.msBackingStorePixelRatio ||\n",
"\tthis.context.oBackingStorePixelRatio ||\n",
"\tthis.context.backingStorePixelRatio || 1;\n",
"\n",
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband = $('');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width * mpl.ratio);\n",
" canvas.attr('height', height * mpl.ratio);\n",
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('');\n",
"\n",
" var fmt_picker = $('');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option)\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('
');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '
';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('');\n",
" var button = $('');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(el){\n",
" var fig = this\n",
" el.on(\"remove\", function(){\n",
"\tfig.close_ws(fig, {});\n",
" });\n",
"}\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"
"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
""
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"% matplotlib notebook\n",
"df.plot(x=\"date\", y=\"close\")"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" date | \n",
" close | \n",
"
\n",
" \n",
" \n",
" \n",
" 781 | \n",
" 2020-03-20 | \n",
" 7.1052 | \n",
"
\n",
" \n",
" 782 | \n",
" 2020-03-23 | \n",
" 7.0940 | \n",
"
\n",
" \n",
" 783 | \n",
" 2020-03-24 | \n",
" 7.0999 | \n",
"
\n",
" \n",
" 788 | \n",
" 2020-03-31 | \n",
" 7.0851 | \n",
"
\n",
" \n",
" 790 | \n",
" 2020-04-02 | \n",
" 7.0995 | \n",
"
\n",
" \n",
" 791 | \n",
" 2020-04-03 | \n",
" 7.1104 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" date close\n",
"781 2020-03-20 7.1052\n",
"782 2020-03-23 7.0940\n",
"783 2020-03-24 7.0999\n",
"788 2020-03-31 7.0851\n",
"790 2020-04-02 7.0995\n",
"791 2020-04-03 7.1104"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df[df[\"close\"] > 7.08]"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" date | \n",
" close | \n",
"
\n",
" \n",
" \n",
" \n",
" 777 | \n",
" 2020-03-16 | \n",
" 7.0018 | \n",
"
\n",
" \n",
" 778 | \n",
" 2020-03-17 | \n",
" 7.0094 | \n",
"
\n",
" \n",
" 779 | \n",
" 2020-03-18 | \n",
" 7.0328 | \n",
"
\n",
" \n",
" 786 | \n",
" 2020-03-27 | \n",
" 7.0427 | \n",
"
\n",
" \n",
" 787 | \n",
" 2020-03-30 | \n",
" 7.0447 | \n",
"
\n",
" \n",
" 780 | \n",
" 2020-03-19 | \n",
" 7.0522 | \n",
"
\n",
" \n",
" 785 | \n",
" 2020-03-26 | \n",
" 7.0692 | \n",
"
\n",
" \n",
" 784 | \n",
" 2020-03-25 | \n",
" 7.0742 | \n",
"
\n",
" \n",
" 789 | \n",
" 2020-04-01 | \n",
" 7.0771 | \n",
"
\n",
" \n",
" 788 | \n",
" 2020-03-31 | \n",
" 7.0851 | \n",
"
\n",
" \n",
" 782 | \n",
" 2020-03-23 | \n",
" 7.0940 | \n",
"
\n",
" \n",
" 790 | \n",
" 2020-04-02 | \n",
" 7.0995 | \n",
"
\n",
" \n",
" 783 | \n",
" 2020-03-24 | \n",
" 7.0999 | \n",
"
\n",
" \n",
" 781 | \n",
" 2020-03-20 | \n",
" 7.1052 | \n",
"
\n",
" \n",
" 791 | \n",
" 2020-04-03 | \n",
" 7.1104 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" date close\n",
"777 2020-03-16 7.0018\n",
"778 2020-03-17 7.0094\n",
"779 2020-03-18 7.0328\n",
"786 2020-03-27 7.0427\n",
"787 2020-03-30 7.0447\n",
"780 2020-03-19 7.0522\n",
"785 2020-03-26 7.0692\n",
"784 2020-03-25 7.0742\n",
"789 2020-04-01 7.0771\n",
"788 2020-03-31 7.0851\n",
"782 2020-03-23 7.0940\n",
"790 2020-04-02 7.0995\n",
"783 2020-03-24 7.0999\n",
"781 2020-03-20 7.1052\n",
"791 2020-04-03 7.1104"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df.sort_values(\"close\")"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"777 NaN\n",
"778 0.001085\n",
"779 0.003338\n",
"780 0.002759\n",
"781 0.007515\n",
"782 -0.001576\n",
"783 0.000832\n",
"784 -0.003620\n",
"785 -0.000707\n",
"786 -0.003749\n",
"787 0.000284\n",
"788 0.005735\n",
"789 -0.001129\n",
"790 0.003165\n",
"791 0.001535\n",
"Name: close, dtype: float64"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df[\"close\"].pct_change()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 使用对比类"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Fetching url: http://fund.eastmoney.com/pingzhongdata/501018.js . Inside function `_basic_init`\n",
"DEBUG:xalpha.cons:Fetching url: http://fund.eastmoney.com/pingzhongdata/501018.js . Inside function `_basic_init`\n",
"Fetching url: http://fund.eastmoney.com/f10/jjfl_501018.html . Inside function `_feepreprocess`\n",
"DEBUG:xalpha.cons:Fetching url: http://fund.eastmoney.com/f10/jjfl_501018.html . Inside function `_feepreprocess`\n",
"Fetching url: http://fund.eastmoney.com/pingzhongdata/160216.js . Inside function `_basic_init`\n",
"DEBUG:xalpha.cons:Fetching url: http://fund.eastmoney.com/pingzhongdata/160216.js . Inside function `_basic_init`\n",
"Fetching url: http://fund.eastmoney.com/f10/jjfl_160216.html . Inside function `_feepreprocess`\n",
"DEBUG:xalpha.cons:Fetching url: http://fund.eastmoney.com/f10/jjfl_160216.html . Inside function `_feepreprocess`\n"
]
},
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support.' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" if (mpl.ratio != 1) {\n",
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
" }\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" fig.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '');\n",
" var titletext = $(\n",
" '');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var backingStore = this.context.backingStorePixelRatio ||\n",
"\tthis.context.webkitBackingStorePixelRatio ||\n",
"\tthis.context.mozBackingStorePixelRatio ||\n",
"\tthis.context.msBackingStorePixelRatio ||\n",
"\tthis.context.oBackingStorePixelRatio ||\n",
"\tthis.context.backingStorePixelRatio || 1;\n",
"\n",
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband = $('');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width * mpl.ratio);\n",
" canvas.attr('height', height * mpl.ratio);\n",
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('');\n",
"\n",
" var fmt_picker = $('');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option)\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width, fig.canvas.height);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"jpeg\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\", \"tif\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overriden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('
');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '
';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('')\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('');\n",
" var button = $('');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(el){\n",
" var fig = this\n",
" el.on(\"remove\", function(){\n",
"\tfig.close_ws(fig, {});\n",
" });\n",
"}\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" event.shiftKey = false;\n",
" // Send a \"J\" for go to next cell\n",
" event.which = 74;\n",
" event.keyCode = 74;\n",
" manager.command_mode();\n",
" manager.handle_keydown(event);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"
"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
""
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"c = xa.Compare((\"commodities/crude-oil\", \"USD\"), \"F501018\", \"F160216\", start=\"20190101\")\n",
"c.v()"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" commodities/crude-oil | \n",
" F501018 | \n",
" F160216 | \n",
"
\n",
" \n",
" \n",
" \n",
" commodities/crude-oil | \n",
" 1.000000 | \n",
" 0.870583 | \n",
" 0.934701 | \n",
"
\n",
" \n",
" F501018 | \n",
" 0.870583 | \n",
" 1.000000 | \n",
" 0.952503 | \n",
"
\n",
" \n",
" F160216 | \n",
" 0.934701 | \n",
" 0.952503 | \n",
" 1.000000 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" commodities/crude-oil F501018 F160216\n",
"commodities/crude-oil 1.000000 0.870583 0.934701\n",
"F501018 0.870583 1.000000 0.952503\n",
"F160216 0.934701 0.952503 1.000000"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"c.corr() # 打印关联系数"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 使用聚宽数据"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# 使用聚宽数据需要激活数据源,如果之前没有激活的话\n",
"user = \"jquser\"\n",
"passw = \"jqpassw\"\n",
"xa.provider.set_jq_data(user, passw)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" id | \n",
" stat_month | \n",
" retail_sin | \n",
" retail_acc | \n",
" retail_sin_yoy | \n",
" retail_acc_yoy | \n",
" scale_retail_sin | \n",
" scale_retail_acc | \n",
" scale_retail_sin_yoy | \n",
" scale_retail_acc_yoy | \n",
" ... | \n",
" hotel_scale_retail_acc_yoy | \n",
" sale_retail_sin | \n",
" sale_retail_acc | \n",
" sale_retail_sin_yoy | \n",
" sale_retail_acc_yoy | \n",
" sale_scale_retail_sin | \n",
" sale_scale_retail_acc | \n",
" sale_scale_retail_sin_yoy | \n",
" sale_scale_retail_acc_yoy | \n",
" date | \n",
"
\n",
" \n",
" \n",
" \n",
" 1 | \n",
" 404 | \n",
" 2018-03-01 | \n",
" 29193.6000 | \n",
" 90275.4000 | \n",
" 10.1000 | \n",
" 9.8000 | \n",
" 11831.8000 | \n",
" 34941.0000 | \n",
" 9.0000 | \n",
" 8.5000 | \n",
" ... | \n",
" 8.0000 | \n",
" 26095.0000 | \n",
" 80563.9000 | \n",
" 10.0000 | \n",
" 9.800 | \n",
" 11112.5000 | \n",
" 32754.7000 | \n",
" 8.9000 | \n",
" 8.6000 | \n",
" 2018-03-01 | \n",
"
\n",
" \n",
" 2 | \n",
" 405 | \n",
" 2018-04-01 | \n",
" 28541.9000 | \n",
" 118817.3000 | \n",
" 9.4000 | \n",
" 9.7000 | \n",
" 11240.6000 | \n",
" 46136.9000 | \n",
" 7.8000 | \n",
" 8.4000 | \n",
" ... | \n",
" 7.7000 | \n",
" 25517.4000 | \n",
" 106081.3000 | \n",
" 9.4000 | \n",
" 9.700 | \n",
" 10540.4000 | \n",
" 43247.9000 | \n",
" 7.8000 | \n",
" 8.4000 | \n",
" 2018-04-01 | \n",
"
\n",
" \n",
" 3 | \n",
" 406 | \n",
" 2018-05-01 | \n",
" 30359.1000 | \n",
" 149176.4000 | \n",
" 8.5000 | \n",
" 9.5000 | \n",
" 11476.7000 | \n",
" 57517.7000 | \n",
" 5.5000 | \n",
" 7.8000 | \n",
" ... | \n",
" 7.1000 | \n",
" 27038.4000 | \n",
" 133119.7000 | \n",
" 8.4000 | \n",
" 9.400 | \n",
" 10735.6000 | \n",
" 53888.1000 | \n",
" 5.6000 | \n",
" 7.8000 | \n",
" 2018-05-01 | \n",
"
\n",
" \n",
" 4 | \n",
" 407 | \n",
" 2018-06-01 | \n",
" 30841.6000 | \n",
" 180017.9000 | \n",
" 9.0000 | \n",
" 9.4000 | \n",
" 12448.3000 | \n",
" 69937.6000 | \n",
" 6.5000 | \n",
" 7.5000 | \n",
" ... | \n",
" 7.2000 | \n",
" 27441.0000 | \n",
" 160560.7000 | \n",
" 8.9000 | \n",
" 9.300 | \n",
" 11671.3000 | \n",
" 65538.2000 | \n",
" 6.4000 | \n",
" 7.6000 | \n",
" 2018-06-01 | \n",
"
\n",
" \n",
" 5 | \n",
" 419 | \n",
" 2018-07-01 | \n",
" 30733.7000 | \n",
" 210751.6000 | \n",
" 8.8000 | \n",
" 9.3000 | \n",
" 11419.0000 | \n",
" 81125.2000 | \n",
" 5.7000 | \n",
" 7.3000 | \n",
" ... | \n",
" 7.0000 | \n",
" 27390.5000 | \n",
" 187951.2000 | \n",
" 8.7000 | \n",
" 9.200 | \n",
" 10655.2000 | \n",
" 75978.8000 | \n",
" 5.7000 | \n",
" 7.3000 | \n",
" 2018-07-01 | \n",
"
\n",
" \n",
" 6 | \n",
" 420 | \n",
" 2018-08-01 | \n",
" 31542.3000 | \n",
" 242293.9000 | \n",
" 9.0000 | \n",
" 9.3000 | \n",
" 11832.2000 | \n",
" 92367.7000 | \n",
" 6.0000 | \n",
" 7.1000 | \n",
" ... | \n",
" 7.1000 | \n",
" 28026.2000 | \n",
" 215977.4000 | \n",
" 8.9000 | \n",
" 9.200 | \n",
" 11041.1000 | \n",
" 86460.3000 | \n",
" 5.9000 | \n",
" 7.1000 | \n",
" 2018-08-01 | \n",
"
\n",
" \n",
" 7 | \n",
" 421 | \n",
" 2018-09-01 | \n",
" 32005.4000 | \n",
" 274299.3000 | \n",
" 9.2000 | \n",
" 9.3000 | \n",
" 12761.7000 | \n",
" 104792.1000 | \n",
" 5.7000 | \n",
" 6.9000 | \n",
" ... | \n",
" 7.0000 | \n",
" 28558.5000 | \n",
" 244535.9000 | \n",
" 9.2000 | \n",
" 9.200 | \n",
" 11961.6000 | \n",
" 98099.3000 | \n",
" 5.6000 | \n",
" 6.9000 | \n",
" 2018-09-01 | \n",
"
\n",
" \n",
" 8 | \n",
" 422 | \n",
" 2018-10-01 | \n",
" 35534.4000 | \n",
" 309833.7000 | \n",
" 8.6000 | \n",
" 9.2000 | \n",
" 12478.6000 | \n",
" 117177.5000 | \n",
" 3.7000 | \n",
" 6.6000 | \n",
" ... | \n",
" 6.8000 | \n",
" 31528.4000 | \n",
" 276064.3000 | \n",
" 8.5000 | \n",
" 9.100 | \n",
" 11630.1000 | \n",
" 109637.1000 | \n",
" 3.6000 | \n",
" 6.6000 | \n",
" 2018-10-01 | \n",
"
\n",
" \n",
" 9 | \n",
" 423 | \n",
" 2018-11-01 | \n",
" 35259.7000 | \n",
" 345093.4000 | \n",
" 8.1000 | \n",
" 9.1000 | \n",
" 13678.7000 | \n",
" 130829.9000 | \n",
" 2.1000 | \n",
" 6.1000 | \n",
" ... | \n",
" 6.5000 | \n",
" 30734.7000 | \n",
" 306799.1000 | \n",
" 8.0000 | \n",
" 9.000 | \n",
" 12862.1000 | \n",
" 122473.1000 | \n",
" 2.0000 | \n",
" 6.1000 | \n",
" 2018-11-01 | \n",
"
\n",
" \n",
" 10 | \n",
" 424 | \n",
" 2018-12-01 | \n",
" 35893.4983 | \n",
" 380986.8522 | \n",
" 8.1608 | \n",
" 8.9817 | \n",
" 15084.0071 | \n",
" 145311.2873 | \n",
" 2.4369 | \n",
" 5.7055 | \n",
" ... | \n",
" 6.4283 | \n",
" 31471.9353 | \n",
" 338270.9998 | \n",
" 8.0408 | \n",
" 8.921 | \n",
" 14174.7441 | \n",
" 136074.9283 | \n",
" 2.2457 | \n",
" 5.6575 | \n",
" 2018-12-01 | \n",
"
\n",
" \n",
" 11 | \n",
" 425 | \n",
" 2019-02-01 | \n",
" 0.0000 | \n",
" 66064.0000 | \n",
" 0.0000 | \n",
" 8.2000 | \n",
" 0.0000 | \n",
" 23096.0000 | \n",
" 0.0000 | \n",
" 3.5000 | \n",
" ... | \n",
" 8.1000 | \n",
" 0.0000 | \n",
" 58813.0000 | \n",
" 0.0000 | \n",
" 8.000 | \n",
" 0.0000 | \n",
" 21580.0000 | \n",
" 0.0000 | \n",
" 3.2000 | \n",
" 2019-02-01 | \n",
"
\n",
" \n",
" 12 | \n",
" 426 | \n",
" 2019-03-01 | \n",
" 31725.7000 | \n",
" 97789.7000 | \n",
" 8.7000 | \n",
" 8.3000 | \n",
" 11952.5000 | \n",
" 35078.2000 | \n",
" 5.1000 | \n",
" 4.1000 | \n",
" ... | \n",
" 7.9000 | \n",
" 28332.8000 | \n",
" 87145.7000 | \n",
" 8.6000 | \n",
" 8.200 | \n",
" 11226.8000 | \n",
" 32852.4000 | \n",
" 5.0000 | \n",
" 3.8000 | \n",
" 2019-03-01 | \n",
"
\n",
" \n",
" 13 | \n",
" 427 | \n",
" 2019-04-01 | \n",
" 30586.1000 | \n",
" 128375.8000 | \n",
" 7.2000 | \n",
" 8.0000 | \n",
" 11120.1000 | \n",
" 46211.9000 | \n",
" 2.0000 | \n",
" 3.5000 | \n",
" ... | \n",
" 7.1000 | \n",
" 27305.3000 | \n",
" 114451.0000 | \n",
" 7.0000 | \n",
" 7.900 | \n",
" 10428.8000 | \n",
" 43291.3000 | \n",
" 1.8000 | \n",
" 3.3000 | \n",
" 2019-04-01 | \n",
"
\n",
" \n",
" 14 | \n",
" 428 | \n",
" 2019-05-01 | \n",
" 32955.7000 | \n",
" 161331.6000 | \n",
" 8.6000 | \n",
" 8.1000 | \n",
" 11693.8000 | \n",
" 57924.0000 | \n",
" 5.1000 | \n",
" 3.9000 | \n",
" ... | \n",
" 7.1000 | \n",
" 29324.4000 | \n",
" 143775.4000 | \n",
" 8.5000 | \n",
" 8.000 | \n",
" 10939.0000 | \n",
" 54222.2000 | \n",
" 5.0000 | \n",
" 3.6000 | \n",
" 2019-05-01 | \n",
"
\n",
" \n",
" 15 | \n",
" 429 | \n",
" 2019-06-01 | \n",
" 33878.1000 | \n",
" 195209.7000 | \n",
" 9.8000 | \n",
" 8.4000 | \n",
" 13163.4000 | \n",
" 71124.2000 | \n",
" 9.7000 | \n",
" 4.9000 | \n",
" ... | \n",
" 7.2000 | \n",
" 30154.8000 | \n",
" 173930.2000 | \n",
" 9.9000 | \n",
" 8.300 | \n",
" 12374.7000 | \n",
" 66627.1000 | \n",
" 9.8000 | \n",
" 4.7000 | \n",
" 2019-06-01 | \n",
"
\n",
" \n",
" 16 | \n",
" 431 | \n",
" 2019-07-01 | \n",
" 33073.3000 | \n",
" 228282.9000 | \n",
" 7.6000 | \n",
" 8.3000 | \n",
" 11412.1000 | \n",
" 82446.2000 | \n",
" 2.9000 | \n",
" 4.6000 | \n",
" ... | \n",
" 7.2000 | \n",
" 29415.2000 | \n",
" 203345.4000 | \n",
" 7.4000 | \n",
" 8.200 | \n",
" 10634.8000 | \n",
" 77208.1000 | \n",
" 2.6000 | \n",
" 4.4000 | \n",
" 2019-07-01 | \n",
"
\n",
" \n",
" 17 | \n",
" 432 | \n",
" 2019-08-01 | \n",
" 33896.3000 | \n",
" 262179.3000 | \n",
" 7.5000 | \n",
" 8.2000 | \n",
" 11772.1000 | \n",
" 93880.9000 | \n",
" 2.0000 | \n",
" 4.3000 | \n",
" ... | \n",
" 7.3000 | \n",
" 30039.2000 | \n",
" 233384.6000 | \n",
" 7.2000 | \n",
" 8.100 | \n",
" 10957.4000 | \n",
" 87832.6000 | \n",
" 1.6000 | \n",
" 4.1000 | \n",
" 2019-08-01 | \n",
"
\n",
" \n",
" 18 | \n",
" 434 | \n",
" 2019-09-01 | \n",
" 34494.9000 | \n",
" 296674.2000 | \n",
" 7.8000 | \n",
" 8.2000 | \n",
" 12835.4000 | \n",
" 106691.9000 | \n",
" 3.1000 | \n",
" 4.1000 | \n",
" ... | \n",
" 7.3000 | \n",
" 30724.7000 | \n",
" 264109.3000 | \n",
" 7.6000 | \n",
" 8.000 | \n",
" 12020.9000 | \n",
" 99829.8000 | \n",
" 2.9000 | \n",
" 3.9000 | \n",
" 2019-09-01 | \n",
"
\n",
" \n",
" 19 | \n",
" 435 | \n",
" 2019-10-01 | \n",
" 38104.3000 | \n",
" 334778.5000 | \n",
" 7.2000 | \n",
" 8.1000 | \n",
" 12322.1000 | \n",
" 118918.8000 | \n",
" 1.2000 | \n",
" 3.8000 | \n",
" ... | \n",
" 7.1000 | \n",
" 33736.9000 | \n",
" 297846.2000 | \n",
" 7.0000 | \n",
" 7.900 | \n",
" 11475.9000 | \n",
" 111223.6000 | \n",
" 0.9000 | \n",
" 3.6000 | \n",
" 2019-10-01 | \n",
"
\n",
" \n",
" 20 | \n",
" 436 | \n",
" 2019-11-01 | \n",
" 38093.8000 | \n",
" 372872.3000 | \n",
" 8.0000 | \n",
" 8.0000 | \n",
" 13964.7000 | \n",
" 132639.1000 | \n",
" 4.4000 | \n",
" 3.9000 | \n",
" ... | \n",
" 7.2000 | \n",
" 33130.1000 | \n",
" 330976.3000 | \n",
" 7.8000 | \n",
" 7.900 | \n",
" 13133.7000 | \n",
" 124111.0000 | \n",
" 4.2000 | \n",
" 3.7000 | \n",
" 2019-11-01 | \n",
"
\n",
" \n",
" 21 | \n",
" 437 | \n",
" 2019-12-01 | \n",
" 38776.7000 | \n",
" 411649.0000 | \n",
" 8.0000 | \n",
" 8.0000 | \n",
" 15337.6000 | \n",
" 148009.9000 | \n",
" 4.4000 | \n",
" 3.9000 | \n",
" ... | \n",
" 7.1000 | \n",
" 33952.1000 | \n",
" 364928.3000 | \n",
" 7.9000 | \n",
" 7.900 | \n",
" 14423.6000 | \n",
" 138565.1000 | \n",
" 4.3000 | \n",
" 3.7000 | \n",
" 2019-12-01 | \n",
"
\n",
" \n",
" 22 | \n",
" 438 | \n",
" 2020-02-01 | \n",
" 0.0000 | \n",
" 52129.8000 | \n",
" 0.0000 | \n",
" -20.5000 | \n",
" 0.0000 | \n",
" 16949.8000 | \n",
" 0.0000 | \n",
" -23.4000 | \n",
" ... | \n",
" -39.7000 | \n",
" 0.0000 | \n",
" 47935.5000 | \n",
" 0.0000 | \n",
" -17.600 | \n",
" 0.0000 | \n",
" 16021.6000 | \n",
" 0.0000 | \n",
" -22.2000 | \n",
" 2020-02-01 | \n",
"
\n",
" \n",
"
\n",
"
22 rows × 35 columns
\n",
"
"
],
"text/plain": [
" id stat_month retail_sin retail_acc retail_sin_yoy retail_acc_yoy \\\n",
"1 404 2018-03-01 29193.6000 90275.4000 10.1000 9.8000 \n",
"2 405 2018-04-01 28541.9000 118817.3000 9.4000 9.7000 \n",
"3 406 2018-05-01 30359.1000 149176.4000 8.5000 9.5000 \n",
"4 407 2018-06-01 30841.6000 180017.9000 9.0000 9.4000 \n",
"5 419 2018-07-01 30733.7000 210751.6000 8.8000 9.3000 \n",
"6 420 2018-08-01 31542.3000 242293.9000 9.0000 9.3000 \n",
"7 421 2018-09-01 32005.4000 274299.3000 9.2000 9.3000 \n",
"8 422 2018-10-01 35534.4000 309833.7000 8.6000 9.2000 \n",
"9 423 2018-11-01 35259.7000 345093.4000 8.1000 9.1000 \n",
"10 424 2018-12-01 35893.4983 380986.8522 8.1608 8.9817 \n",
"11 425 2019-02-01 0.0000 66064.0000 0.0000 8.2000 \n",
"12 426 2019-03-01 31725.7000 97789.7000 8.7000 8.3000 \n",
"13 427 2019-04-01 30586.1000 128375.8000 7.2000 8.0000 \n",
"14 428 2019-05-01 32955.7000 161331.6000 8.6000 8.1000 \n",
"15 429 2019-06-01 33878.1000 195209.7000 9.8000 8.4000 \n",
"16 431 2019-07-01 33073.3000 228282.9000 7.6000 8.3000 \n",
"17 432 2019-08-01 33896.3000 262179.3000 7.5000 8.2000 \n",
"18 434 2019-09-01 34494.9000 296674.2000 7.8000 8.2000 \n",
"19 435 2019-10-01 38104.3000 334778.5000 7.2000 8.1000 \n",
"20 436 2019-11-01 38093.8000 372872.3000 8.0000 8.0000 \n",
"21 437 2019-12-01 38776.7000 411649.0000 8.0000 8.0000 \n",
"22 438 2020-02-01 0.0000 52129.8000 0.0000 -20.5000 \n",
"\n",
" scale_retail_sin scale_retail_acc scale_retail_sin_yoy \\\n",
"1 11831.8000 34941.0000 9.0000 \n",
"2 11240.6000 46136.9000 7.8000 \n",
"3 11476.7000 57517.7000 5.5000 \n",
"4 12448.3000 69937.6000 6.5000 \n",
"5 11419.0000 81125.2000 5.7000 \n",
"6 11832.2000 92367.7000 6.0000 \n",
"7 12761.7000 104792.1000 5.7000 \n",
"8 12478.6000 117177.5000 3.7000 \n",
"9 13678.7000 130829.9000 2.1000 \n",
"10 15084.0071 145311.2873 2.4369 \n",
"11 0.0000 23096.0000 0.0000 \n",
"12 11952.5000 35078.2000 5.1000 \n",
"13 11120.1000 46211.9000 2.0000 \n",
"14 11693.8000 57924.0000 5.1000 \n",
"15 13163.4000 71124.2000 9.7000 \n",
"16 11412.1000 82446.2000 2.9000 \n",
"17 11772.1000 93880.9000 2.0000 \n",
"18 12835.4000 106691.9000 3.1000 \n",
"19 12322.1000 118918.8000 1.2000 \n",
"20 13964.7000 132639.1000 4.4000 \n",
"21 15337.6000 148009.9000 4.4000 \n",
"22 0.0000 16949.8000 0.0000 \n",
"\n",
" scale_retail_acc_yoy ... hotel_scale_retail_acc_yoy sale_retail_sin \\\n",
"1 8.5000 ... 8.0000 26095.0000 \n",
"2 8.4000 ... 7.7000 25517.4000 \n",
"3 7.8000 ... 7.1000 27038.4000 \n",
"4 7.5000 ... 7.2000 27441.0000 \n",
"5 7.3000 ... 7.0000 27390.5000 \n",
"6 7.1000 ... 7.1000 28026.2000 \n",
"7 6.9000 ... 7.0000 28558.5000 \n",
"8 6.6000 ... 6.8000 31528.4000 \n",
"9 6.1000 ... 6.5000 30734.7000 \n",
"10 5.7055 ... 6.4283 31471.9353 \n",
"11 3.5000 ... 8.1000 0.0000 \n",
"12 4.1000 ... 7.9000 28332.8000 \n",
"13 3.5000 ... 7.1000 27305.3000 \n",
"14 3.9000 ... 7.1000 29324.4000 \n",
"15 4.9000 ... 7.2000 30154.8000 \n",
"16 4.6000 ... 7.2000 29415.2000 \n",
"17 4.3000 ... 7.3000 30039.2000 \n",
"18 4.1000 ... 7.3000 30724.7000 \n",
"19 3.8000 ... 7.1000 33736.9000 \n",
"20 3.9000 ... 7.2000 33130.1000 \n",
"21 3.9000 ... 7.1000 33952.1000 \n",
"22 -23.4000 ... -39.7000 0.0000 \n",
"\n",
" sale_retail_acc sale_retail_sin_yoy sale_retail_acc_yoy \\\n",
"1 80563.9000 10.0000 9.800 \n",
"2 106081.3000 9.4000 9.700 \n",
"3 133119.7000 8.4000 9.400 \n",
"4 160560.7000 8.9000 9.300 \n",
"5 187951.2000 8.7000 9.200 \n",
"6 215977.4000 8.9000 9.200 \n",
"7 244535.9000 9.2000 9.200 \n",
"8 276064.3000 8.5000 9.100 \n",
"9 306799.1000 8.0000 9.000 \n",
"10 338270.9998 8.0408 8.921 \n",
"11 58813.0000 0.0000 8.000 \n",
"12 87145.7000 8.6000 8.200 \n",
"13 114451.0000 7.0000 7.900 \n",
"14 143775.4000 8.5000 8.000 \n",
"15 173930.2000 9.9000 8.300 \n",
"16 203345.4000 7.4000 8.200 \n",
"17 233384.6000 7.2000 8.100 \n",
"18 264109.3000 7.6000 8.000 \n",
"19 297846.2000 7.0000 7.900 \n",
"20 330976.3000 7.8000 7.900 \n",
"21 364928.3000 7.9000 7.900 \n",
"22 47935.5000 0.0000 -17.600 \n",
"\n",
" sale_scale_retail_sin sale_scale_retail_acc sale_scale_retail_sin_yoy \\\n",
"1 11112.5000 32754.7000 8.9000 \n",
"2 10540.4000 43247.9000 7.8000 \n",
"3 10735.6000 53888.1000 5.6000 \n",
"4 11671.3000 65538.2000 6.4000 \n",
"5 10655.2000 75978.8000 5.7000 \n",
"6 11041.1000 86460.3000 5.9000 \n",
"7 11961.6000 98099.3000 5.6000 \n",
"8 11630.1000 109637.1000 3.6000 \n",
"9 12862.1000 122473.1000 2.0000 \n",
"10 14174.7441 136074.9283 2.2457 \n",
"11 0.0000 21580.0000 0.0000 \n",
"12 11226.8000 32852.4000 5.0000 \n",
"13 10428.8000 43291.3000 1.8000 \n",
"14 10939.0000 54222.2000 5.0000 \n",
"15 12374.7000 66627.1000 9.8000 \n",
"16 10634.8000 77208.1000 2.6000 \n",
"17 10957.4000 87832.6000 1.6000 \n",
"18 12020.9000 99829.8000 2.9000 \n",
"19 11475.9000 111223.6000 0.9000 \n",
"20 13133.7000 124111.0000 4.2000 \n",
"21 14423.6000 138565.1000 4.3000 \n",
"22 0.0000 16021.6000 0.0000 \n",
"\n",
" sale_scale_retail_acc_yoy date \n",
"1 8.6000 2018-03-01 \n",
"2 8.4000 2018-04-01 \n",
"3 7.8000 2018-05-01 \n",
"4 7.6000 2018-06-01 \n",
"5 7.3000 2018-07-01 \n",
"6 7.1000 2018-08-01 \n",
"7 6.9000 2018-09-01 \n",
"8 6.6000 2018-10-01 \n",
"9 6.1000 2018-11-01 \n",
"10 5.6575 2018-12-01 \n",
"11 3.2000 2019-02-01 \n",
"12 3.8000 2019-03-01 \n",
"13 3.3000 2019-04-01 \n",
"14 3.6000 2019-05-01 \n",
"15 4.7000 2019-06-01 \n",
"16 4.4000 2019-07-01 \n",
"17 4.1000 2019-08-01 \n",
"18 3.9000 2019-09-01 \n",
"19 3.6000 2019-10-01 \n",
"20 3.7000 2019-11-01 \n",
"21 3.7000 2019-12-01 \n",
"22 -22.2000 2020-02-01 \n",
"\n",
"[22 rows x 35 columns]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df = xa.get_daily(\"mcm-MAC_SALE_RETAIL_MONTH\", start=\"20180301\")\n",
"# 获取宏观数据,商品零售总额\n",
"df"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support. ' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" if (mpl.ratio != 1) {\n",
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
" }\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" fig.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '');\n",
" var titletext = $(\n",
" '');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var backingStore = this.context.backingStorePixelRatio ||\n",
"\tthis.context.webkitBackingStorePixelRatio ||\n",
"\tthis.context.mozBackingStorePixelRatio ||\n",
"\tthis.context.msBackingStorePixelRatio ||\n",
"\tthis.context.oBackingStorePixelRatio ||\n",
"\tthis.context.backingStorePixelRatio || 1;\n",
"\n",
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband = $('');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width * mpl.ratio);\n",
" canvas.attr('height', height * mpl.ratio);\n",
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('');\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('');\n",
"\n",
" var fmt_picker = $('');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option);\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width / mpl.ratio, fig.canvas.height / mpl.ratio);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('
');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '
';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('');\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('');\n",
" var button = $('');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(el){\n",
" var fig = this\n",
" el.on(\"remove\", function(){\n",
"\tfig.close_ws(fig, {});\n",
" });\n",
"}\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"
"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
""
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%matplotlib notebook\n",
"df.plot(x=\"date\", y=\"retail_sin\")"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support. ' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" if (mpl.ratio != 1) {\n",
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
" }\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" fig.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '');\n",
" var titletext = $(\n",
" '');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var backingStore = this.context.backingStorePixelRatio ||\n",
"\tthis.context.webkitBackingStorePixelRatio ||\n",
"\tthis.context.mozBackingStorePixelRatio ||\n",
"\tthis.context.msBackingStorePixelRatio ||\n",
"\tthis.context.oBackingStorePixelRatio ||\n",
"\tthis.context.backingStorePixelRatio || 1;\n",
"\n",
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband = $('');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width * mpl.ratio);\n",
" canvas.attr('height', height * mpl.ratio);\n",
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('');\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('');\n",
"\n",
" var fmt_picker = $('');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option);\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width / mpl.ratio, fig.canvas.height / mpl.ratio);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('
');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '
';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('');\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('');\n",
" var button = $('');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(el){\n",
" var fig = this\n",
" el.on(\"remove\", function(){\n",
"\tfig.close_ws(fig, {});\n",
" });\n",
"}\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"
"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
""
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df = xa.get_daily(\"mcd-MAC_LEND_RATE\", start=\"2018-01-01\")\n",
"df = df[(df[\"currency_name\"] == \"人民币\") & (df[\"market_id\"] == 5) & (df[\"term_id\"] == 20)]\n",
"%matplotlib notebook\n",
"df.plot(x=\"date\", y=\"interest_rate\")"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" code | \n",
" date | \n",
" display_name | \n",
" weight | \n",
"
\n",
" \n",
" \n",
" \n",
" 1950 | \n",
" 600000.XSHG | \n",
" 2020-04-01 | \n",
" 浦发银行 | \n",
" 1.812 | \n",
"
\n",
" \n",
" 1951 | \n",
" 600009.XSHG | \n",
" 2020-04-01 | \n",
" 上海机场 | \n",
" 1.668 | \n",
"
\n",
" \n",
" 1952 | \n",
" 600016.XSHG | \n",
" 2020-04-01 | \n",
" 民生银行 | \n",
" 1.953 | \n",
"
\n",
" \n",
" 1953 | \n",
" 600028.XSHG | \n",
" 2020-04-01 | \n",
" 中国石化 | \n",
" 1.901 | \n",
"
\n",
" \n",
" 1954 | \n",
" 600030.XSHG | \n",
" 2020-04-01 | \n",
" 中信证券 | \n",
" 2.290 | \n",
"
\n",
" \n",
" 1955 | \n",
" 600031.XSHG | \n",
" 2020-04-01 | \n",
" 三一重工 | \n",
" 2.363 | \n",
"
\n",
" \n",
" 1956 | \n",
" 600036.XSHG | \n",
" 2020-04-01 | \n",
" 招商银行 | \n",
" 1.891 | \n",
"
\n",
" \n",
" 1957 | \n",
" 600050.XSHG | \n",
" 2020-04-01 | \n",
" 中国联通 | \n",
" 1.959 | \n",
"
\n",
" \n",
" 1958 | \n",
" 600104.XSHG | \n",
" 2020-04-01 | \n",
" 上汽集团 | \n",
" 1.920 | \n",
"
\n",
" \n",
" 1959 | \n",
" 600196.XSHG | \n",
" 2020-04-01 | \n",
" 复星医药 | \n",
" 2.779 | \n",
"
\n",
" \n",
" 1960 | \n",
" 600276.XSHG | \n",
" 2020-04-01 | \n",
" 恒瑞医药 | \n",
" 2.338 | \n",
"
\n",
" \n",
" 1961 | \n",
" 600309.XSHG | \n",
" 2020-04-01 | \n",
" 万华化学 | \n",
" 1.728 | \n",
"
\n",
" \n",
" 1962 | \n",
" 600340.XSHG | \n",
" 2020-04-01 | \n",
" 华夏幸福 | \n",
" 1.615 | \n",
"
\n",
" \n",
" 1963 | \n",
" 600519.XSHG | \n",
" 2020-04-01 | \n",
" 贵州茅台 | \n",
" 2.037 | \n",
"
\n",
" \n",
" 1964 | \n",
" 600547.XSHG | \n",
" 2020-04-01 | \n",
" 山东黄金 | \n",
" 2.345 | \n",
"
\n",
" \n",
" 1965 | \n",
" 600585.XSHG | \n",
" 2020-04-01 | \n",
" 海螺水泥 | \n",
" 2.429 | \n",
"
\n",
" \n",
" 1966 | \n",
" 600690.XSHG | \n",
" 2020-04-01 | \n",
" 海尔智家 | \n",
" 1.812 | \n",
"
\n",
" \n",
" 1967 | \n",
" 600703.XSHG | \n",
" 2020-04-01 | \n",
" 三安光电 | \n",
" 2.338 | \n",
"
\n",
" \n",
" 1968 | \n",
" 600837.XSHG | \n",
" 2020-04-01 | \n",
" 海通证券 | \n",
" 1.923 | \n",
"
\n",
" \n",
" 1969 | \n",
" 600887.XSHG | \n",
" 2020-04-01 | \n",
" 伊利股份 | \n",
" 2.056 | \n",
"
\n",
" \n",
" 1970 | \n",
" 601988.XSHG | \n",
" 2020-04-01 | \n",
" 中国银行 | \n",
" 2.042 | \n",
"
\n",
" \n",
" 1971 | \n",
" 600048.XSHG | \n",
" 2020-04-01 | \n",
" 保利地产 | \n",
" 2.033 | \n",
"
\n",
" \n",
" 1972 | \n",
" 601111.XSHG | \n",
" 2020-04-01 | \n",
" 中国国航 | \n",
" 1.614 | \n",
"
\n",
" \n",
" 1973 | \n",
" 601398.XSHG | \n",
" 2020-04-01 | \n",
" 工商银行 | \n",
" 1.906 | \n",
"
\n",
" \n",
" 1974 | \n",
" 601628.XSHG | \n",
" 2020-04-01 | \n",
" 中国人寿 | \n",
" 1.684 | \n",
"
\n",
" \n",
" 1975 | \n",
" 601166.XSHG | \n",
" 2020-04-01 | \n",
" 兴业银行 | \n",
" 1.787 | \n",
"
\n",
" \n",
" 1976 | \n",
" 601318.XSHG | \n",
" 2020-04-01 | \n",
" 中国平安 | \n",
" 1.757 | \n",
"
\n",
" \n",
" 1977 | \n",
" 601328.XSHG | \n",
" 2020-04-01 | \n",
" 交通银行 | \n",
" 1.993 | \n",
"
\n",
" \n",
" 1978 | \n",
" 601939.XSHG | \n",
" 2020-04-01 | \n",
" 建设银行 | \n",
" 1.899 | \n",
"
\n",
" \n",
" 1979 | \n",
" 601088.XSHG | \n",
" 2020-04-01 | \n",
" 中国神华 | \n",
" 1.972 | \n",
"
\n",
" \n",
" 1980 | \n",
" 601857.XSHG | \n",
" 2020-04-01 | \n",
" 中国石油 | \n",
" 1.737 | \n",
"
\n",
" \n",
" 1981 | \n",
" 601390.XSHG | \n",
" 2020-04-01 | \n",
" 中国中铁 | \n",
" 2.005 | \n",
"
\n",
" \n",
" 1982 | \n",
" 601601.XSHG | \n",
" 2020-04-01 | \n",
" 中国太保 | \n",
" 1.722 | \n",
"
\n",
" \n",
" 1983 | \n",
" 601186.XSHG | \n",
" 2020-04-01 | \n",
" 中国铁建 | \n",
" 2.135 | \n",
"
\n",
" \n",
" 1984 | \n",
" 601668.XSHG | \n",
" 2020-04-01 | \n",
" 中国建筑 | \n",
" 2.140 | \n",
"
\n",
" \n",
" 1985 | \n",
" 601766.XSHG | \n",
" 2020-04-01 | \n",
" 中国中车 | \n",
" 2.005 | \n",
"
\n",
" \n",
" 1986 | \n",
" 601888.XSHG | \n",
" 2020-04-01 | \n",
" 中国国旅 | \n",
" 1.673 | \n",
"
\n",
" \n",
" 1987 | \n",
" 601989.XSHG | \n",
" 2020-04-01 | \n",
" 中国重工 | \n",
" 1.703 | \n",
"
\n",
" \n",
" 1988 | \n",
" 601688.XSHG | \n",
" 2020-04-01 | \n",
" 华泰证券 | \n",
" 2.040 | \n",
"
\n",
" \n",
" 1989 | \n",
" 601012.XSHG | \n",
" 2020-04-01 | \n",
" 隆基股份 | \n",
" 2.092 | \n",
"
\n",
" \n",
" 1990 | \n",
" 601288.XSHG | \n",
" 2020-04-01 | \n",
" 农业银行 | \n",
" 1.983 | \n",
"
\n",
" \n",
" 1991 | \n",
" 601818.XSHG | \n",
" 2020-04-01 | \n",
" 光大银行 | \n",
" 1.839 | \n",
"
\n",
" \n",
" 1992 | \n",
" 601336.XSHG | \n",
" 2020-04-01 | \n",
" 新华保险 | \n",
" 1.846 | \n",
"
\n",
" \n",
" 1993 | \n",
" 603993.XSHG | \n",
" 2020-04-01 | \n",
" 洛阳钼业 | \n",
" 1.971 | \n",
"
\n",
" \n",
" 1994 | \n",
" 601211.XSHG | \n",
" 2020-04-01 | \n",
" 国泰君安 | \n",
" 1.969 | \n",
"
\n",
" \n",
" 1995 | \n",
" 601066.XSHG | \n",
" 2020-04-01 | \n",
" 中信建投 | \n",
" 2.904 | \n",
"
\n",
" \n",
" 1996 | \n",
" 601236.XSHG | \n",
" 2020-04-01 | \n",
" 红塔证券 | \n",
" 2.694 | \n",
"
\n",
" \n",
" 1997 | \n",
" 603259.XSHG | \n",
" 2020-04-01 | \n",
" 药明康德 | \n",
" 2.124 | \n",
"
\n",
" \n",
" 1998 | \n",
" 601319.XSHG | \n",
" 2020-04-01 | \n",
" 中国人保 | \n",
" 1.974 | \n",
"
\n",
" \n",
" 1999 | \n",
" 601138.XSHG | \n",
" 2020-04-01 | \n",
" 工业富联 | \n",
" 1.601 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" code date display_name weight\n",
"1950 600000.XSHG 2020-04-01 浦发银行 1.812\n",
"1951 600009.XSHG 2020-04-01 上海机场 1.668\n",
"1952 600016.XSHG 2020-04-01 民生银行 1.953\n",
"1953 600028.XSHG 2020-04-01 中国石化 1.901\n",
"1954 600030.XSHG 2020-04-01 中信证券 2.290\n",
"1955 600031.XSHG 2020-04-01 三一重工 2.363\n",
"1956 600036.XSHG 2020-04-01 招商银行 1.891\n",
"1957 600050.XSHG 2020-04-01 中国联通 1.959\n",
"1958 600104.XSHG 2020-04-01 上汽集团 1.920\n",
"1959 600196.XSHG 2020-04-01 复星医药 2.779\n",
"1960 600276.XSHG 2020-04-01 恒瑞医药 2.338\n",
"1961 600309.XSHG 2020-04-01 万华化学 1.728\n",
"1962 600340.XSHG 2020-04-01 华夏幸福 1.615\n",
"1963 600519.XSHG 2020-04-01 贵州茅台 2.037\n",
"1964 600547.XSHG 2020-04-01 山东黄金 2.345\n",
"1965 600585.XSHG 2020-04-01 海螺水泥 2.429\n",
"1966 600690.XSHG 2020-04-01 海尔智家 1.812\n",
"1967 600703.XSHG 2020-04-01 三安光电 2.338\n",
"1968 600837.XSHG 2020-04-01 海通证券 1.923\n",
"1969 600887.XSHG 2020-04-01 伊利股份 2.056\n",
"1970 601988.XSHG 2020-04-01 中国银行 2.042\n",
"1971 600048.XSHG 2020-04-01 保利地产 2.033\n",
"1972 601111.XSHG 2020-04-01 中国国航 1.614\n",
"1973 601398.XSHG 2020-04-01 工商银行 1.906\n",
"1974 601628.XSHG 2020-04-01 中国人寿 1.684\n",
"1975 601166.XSHG 2020-04-01 兴业银行 1.787\n",
"1976 601318.XSHG 2020-04-01 中国平安 1.757\n",
"1977 601328.XSHG 2020-04-01 交通银行 1.993\n",
"1978 601939.XSHG 2020-04-01 建设银行 1.899\n",
"1979 601088.XSHG 2020-04-01 中国神华 1.972\n",
"1980 601857.XSHG 2020-04-01 中国石油 1.737\n",
"1981 601390.XSHG 2020-04-01 中国中铁 2.005\n",
"1982 601601.XSHG 2020-04-01 中国太保 1.722\n",
"1983 601186.XSHG 2020-04-01 中国铁建 2.135\n",
"1984 601668.XSHG 2020-04-01 中国建筑 2.140\n",
"1985 601766.XSHG 2020-04-01 中国中车 2.005\n",
"1986 601888.XSHG 2020-04-01 中国国旅 1.673\n",
"1987 601989.XSHG 2020-04-01 中国重工 1.703\n",
"1988 601688.XSHG 2020-04-01 华泰证券 2.040\n",
"1989 601012.XSHG 2020-04-01 隆基股份 2.092\n",
"1990 601288.XSHG 2020-04-01 农业银行 1.983\n",
"1991 601818.XSHG 2020-04-01 光大银行 1.839\n",
"1992 601336.XSHG 2020-04-01 新华保险 1.846\n",
"1993 603993.XSHG 2020-04-01 洛阳钼业 1.971\n",
"1994 601211.XSHG 2020-04-01 国泰君安 1.969\n",
"1995 601066.XSHG 2020-04-01 中信建投 2.904\n",
"1996 601236.XSHG 2020-04-01 红塔证券 2.694\n",
"1997 603259.XSHG 2020-04-01 药明康德 2.124\n",
"1998 601319.XSHG 2020-04-01 中国人保 1.974\n",
"1999 601138.XSHG 2020-04-01 工业富联 1.601"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 指数成分股和权重\n",
"xa.get_daily(\"iw-SH000050\", start=\"20200331\", end=\"20200405\")"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support. ' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" if (mpl.ratio != 1) {\n",
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
" }\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" fig.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '');\n",
" var titletext = $(\n",
" '');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var backingStore = this.context.backingStorePixelRatio ||\n",
"\tthis.context.webkitBackingStorePixelRatio ||\n",
"\tthis.context.mozBackingStorePixelRatio ||\n",
"\tthis.context.msBackingStorePixelRatio ||\n",
"\tthis.context.oBackingStorePixelRatio ||\n",
"\tthis.context.backingStorePixelRatio || 1;\n",
"\n",
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband = $('');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width * mpl.ratio);\n",
" canvas.attr('height', height * mpl.ratio);\n",
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('');\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('');\n",
"\n",
" var fmt_picker = $('');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option);\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width / mpl.ratio, fig.canvas.height / mpl.ratio);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('
');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '
';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('');\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('');\n",
" var button = $('');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(el){\n",
" var fig = this\n",
" el.on(\"remove\", function(){\n",
"\tfig.close_ws(fig, {});\n",
" });\n",
"}\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"
"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
""
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 场内基金份额\n",
"df = xa.get_daily(\"fs-SZ161129\", start=\"20200201\")\n",
"df.plot(x=\"date\", y=\"shares\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"根据实际权重的指数估值分析"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Fetching url: https://stock.xueqiu.com/v5/stock/quote.json?symbol=SH000050&extend=detail . Inside function `get_xueqiu_rt`\n"
]
}
],
"source": [
"h = xa.PEBHistory(\"SH000050\", start=\"2013-01-01\")"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Fetching url: https://stock.xueqiu.com/v5/stock/chart/kline.json?symbol=SH000050&begin=1586072240181&period=day&type=before&count=-1190 . Inside function `get_history`\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"指数50等权估值情况\n",
"\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Fetching url: https://stock.xueqiu.com/v5/stock/quote.json?symbol=SH000050&extend=detail . Inside function `get_xueqiu_rt`\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"现在 PE 绝对值 10.801, 相对分位 24.27%,距离最低点 12.9 %\n",
"\n",
"现在 PB 绝对值 1.305, 相对分位 4.22%,距离最低点 8.0 %\n",
"\n"
]
}
],
"source": [
"h.summary()"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"/* Put everything inside the global mpl namespace */\n",
"window.mpl = {};\n",
"\n",
"\n",
"mpl.get_websocket_type = function() {\n",
" if (typeof(WebSocket) !== 'undefined') {\n",
" return WebSocket;\n",
" } else if (typeof(MozWebSocket) !== 'undefined') {\n",
" return MozWebSocket;\n",
" } else {\n",
" alert('Your browser does not have WebSocket support. ' +\n",
" 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n",
" 'Firefox 4 and 5 are also supported but you ' +\n",
" 'have to enable WebSockets in about:config.');\n",
" };\n",
"}\n",
"\n",
"mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n",
" this.id = figure_id;\n",
"\n",
" this.ws = websocket;\n",
"\n",
" this.supports_binary = (this.ws.binaryType != undefined);\n",
"\n",
" if (!this.supports_binary) {\n",
" var warnings = document.getElementById(\"mpl-warnings\");\n",
" if (warnings) {\n",
" warnings.style.display = 'block';\n",
" warnings.textContent = (\n",
" \"This browser does not support binary websocket messages. \" +\n",
" \"Performance may be slow.\");\n",
" }\n",
" }\n",
"\n",
" this.imageObj = new Image();\n",
"\n",
" this.context = undefined;\n",
" this.message = undefined;\n",
" this.canvas = undefined;\n",
" this.rubberband_canvas = undefined;\n",
" this.rubberband_context = undefined;\n",
" this.format_dropdown = undefined;\n",
"\n",
" this.image_mode = 'full';\n",
"\n",
" this.root = $('');\n",
" this._root_extra_style(this.root)\n",
" this.root.attr('style', 'display: inline-block');\n",
"\n",
" $(parent_element).append(this.root);\n",
"\n",
" this._init_header(this);\n",
" this._init_canvas(this);\n",
" this._init_toolbar(this);\n",
"\n",
" var fig = this;\n",
"\n",
" this.waiting = false;\n",
"\n",
" this.ws.onopen = function () {\n",
" fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n",
" fig.send_message(\"send_image_mode\", {});\n",
" if (mpl.ratio != 1) {\n",
" fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n",
" }\n",
" fig.send_message(\"refresh\", {});\n",
" }\n",
"\n",
" this.imageObj.onload = function() {\n",
" if (fig.image_mode == 'full') {\n",
" // Full images could contain transparency (where diff images\n",
" // almost always do), so we need to clear the canvas so that\n",
" // there is no ghosting.\n",
" fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n",
" }\n",
" fig.context.drawImage(fig.imageObj, 0, 0);\n",
" };\n",
"\n",
" this.imageObj.onunload = function() {\n",
" fig.ws.close();\n",
" }\n",
"\n",
" this.ws.onmessage = this._make_on_message_function(this);\n",
"\n",
" this.ondownload = ondownload;\n",
"}\n",
"\n",
"mpl.figure.prototype._init_header = function() {\n",
" var titlebar = $(\n",
" '');\n",
" var titletext = $(\n",
" '');\n",
" titlebar.append(titletext)\n",
" this.root.append(titlebar);\n",
" this.header = titletext[0];\n",
"}\n",
"\n",
"\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(canvas_div) {\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._init_canvas = function() {\n",
" var fig = this;\n",
"\n",
" var canvas_div = $('');\n",
"\n",
" canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n",
"\n",
" function canvas_keyboard_event(event) {\n",
" return fig.key_event(event, event['data']);\n",
" }\n",
"\n",
" canvas_div.keydown('key_press', canvas_keyboard_event);\n",
" canvas_div.keyup('key_release', canvas_keyboard_event);\n",
" this.canvas_div = canvas_div\n",
" this._canvas_extra_style(canvas_div)\n",
" this.root.append(canvas_div);\n",
"\n",
" var canvas = $('');\n",
" canvas.addClass('mpl-canvas');\n",
" canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n",
"\n",
" this.canvas = canvas[0];\n",
" this.context = canvas[0].getContext(\"2d\");\n",
"\n",
" var backingStore = this.context.backingStorePixelRatio ||\n",
"\tthis.context.webkitBackingStorePixelRatio ||\n",
"\tthis.context.mozBackingStorePixelRatio ||\n",
"\tthis.context.msBackingStorePixelRatio ||\n",
"\tthis.context.oBackingStorePixelRatio ||\n",
"\tthis.context.backingStorePixelRatio || 1;\n",
"\n",
" mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n",
"\n",
" var rubberband = $('');\n",
" rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n",
"\n",
" var pass_mouse_events = true;\n",
"\n",
" canvas_div.resizable({\n",
" start: function(event, ui) {\n",
" pass_mouse_events = false;\n",
" },\n",
" resize: function(event, ui) {\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" stop: function(event, ui) {\n",
" pass_mouse_events = true;\n",
" fig.request_resize(ui.size.width, ui.size.height);\n",
" },\n",
" });\n",
"\n",
" function mouse_event_fn(event) {\n",
" if (pass_mouse_events)\n",
" return fig.mouse_event(event, event['data']);\n",
" }\n",
"\n",
" rubberband.mousedown('button_press', mouse_event_fn);\n",
" rubberband.mouseup('button_release', mouse_event_fn);\n",
" // Throttle sequential mouse events to 1 every 20ms.\n",
" rubberband.mousemove('motion_notify', mouse_event_fn);\n",
"\n",
" rubberband.mouseenter('figure_enter', mouse_event_fn);\n",
" rubberband.mouseleave('figure_leave', mouse_event_fn);\n",
"\n",
" canvas_div.on(\"wheel\", function (event) {\n",
" event = event.originalEvent;\n",
" event['data'] = 'scroll'\n",
" if (event.deltaY < 0) {\n",
" event.step = 1;\n",
" } else {\n",
" event.step = -1;\n",
" }\n",
" mouse_event_fn(event);\n",
" });\n",
"\n",
" canvas_div.append(canvas);\n",
" canvas_div.append(rubberband);\n",
"\n",
" this.rubberband = rubberband;\n",
" this.rubberband_canvas = rubberband[0];\n",
" this.rubberband_context = rubberband[0].getContext(\"2d\");\n",
" this.rubberband_context.strokeStyle = \"#000000\";\n",
"\n",
" this._resize_canvas = function(width, height) {\n",
" // Keep the size of the canvas, canvas container, and rubber band\n",
" // canvas in synch.\n",
" canvas_div.css('width', width)\n",
" canvas_div.css('height', height)\n",
"\n",
" canvas.attr('width', width * mpl.ratio);\n",
" canvas.attr('height', height * mpl.ratio);\n",
" canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n",
"\n",
" rubberband.attr('width', width);\n",
" rubberband.attr('height', height);\n",
" }\n",
"\n",
" // Set the figure to an initial 600x600px, this will subsequently be updated\n",
" // upon first draw.\n",
" this._resize_canvas(600, 600);\n",
"\n",
" // Disable right mouse context menu.\n",
" $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n",
" return false;\n",
" });\n",
"\n",
" function set_focus () {\n",
" canvas.focus();\n",
" canvas_div.focus();\n",
" }\n",
"\n",
" window.setTimeout(set_focus, 100);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('');\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items) {\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) {\n",
" // put a spacer in here.\n",
" continue;\n",
" }\n",
" var button = $('');\n",
" button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +\n",
" 'ui-button-icon-only');\n",
" button.attr('role', 'button');\n",
" button.attr('aria-disabled', 'false');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
"\n",
" var icon_img = $('');\n",
" icon_img.addClass('ui-button-icon-primary ui-icon');\n",
" icon_img.addClass(image);\n",
" icon_img.addClass('ui-corner-all');\n",
"\n",
" var tooltip_span = $('');\n",
" tooltip_span.addClass('ui-button-text');\n",
" tooltip_span.html(tooltip);\n",
"\n",
" button.append(icon_img);\n",
" button.append(tooltip_span);\n",
"\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" var fmt_picker_span = $('');\n",
"\n",
" var fmt_picker = $('');\n",
" fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');\n",
" fmt_picker_span.append(fmt_picker);\n",
" nav_element.append(fmt_picker_span);\n",
" this.format_dropdown = fmt_picker[0];\n",
"\n",
" for (var ind in mpl.extensions) {\n",
" var fmt = mpl.extensions[ind];\n",
" var option = $(\n",
" '', {selected: fmt === mpl.default_extension}).html(fmt);\n",
" fmt_picker.append(option);\n",
" }\n",
"\n",
" // Add hover states to the ui-buttons\n",
" $( \".ui-button\" ).hover(\n",
" function() { $(this).addClass(\"ui-state-hover\");},\n",
" function() { $(this).removeClass(\"ui-state-hover\");}\n",
" );\n",
"\n",
" var status_bar = $('');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"}\n",
"\n",
"mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {\n",
" // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,\n",
" // which will in turn request a refresh of the image.\n",
" this.send_message('resize', {'width': x_pixels, 'height': y_pixels});\n",
"}\n",
"\n",
"mpl.figure.prototype.send_message = function(type, properties) {\n",
" properties['type'] = type;\n",
" properties['figure_id'] = this.id;\n",
" this.ws.send(JSON.stringify(properties));\n",
"}\n",
"\n",
"mpl.figure.prototype.send_draw_message = function() {\n",
" if (!this.waiting) {\n",
" this.waiting = true;\n",
" this.ws.send(JSON.stringify({type: \"draw\", figure_id: this.id}));\n",
" }\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" var format_dropdown = fig.format_dropdown;\n",
" var format = format_dropdown.options[format_dropdown.selectedIndex].value;\n",
" fig.ondownload(fig, format);\n",
"}\n",
"\n",
"\n",
"mpl.figure.prototype.handle_resize = function(fig, msg) {\n",
" var size = msg['size'];\n",
" if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {\n",
" fig._resize_canvas(size[0], size[1]);\n",
" fig.send_message(\"refresh\", {});\n",
" };\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_rubberband = function(fig, msg) {\n",
" var x0 = msg['x0'] / mpl.ratio;\n",
" var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;\n",
" var x1 = msg['x1'] / mpl.ratio;\n",
" var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;\n",
" x0 = Math.floor(x0) + 0.5;\n",
" y0 = Math.floor(y0) + 0.5;\n",
" x1 = Math.floor(x1) + 0.5;\n",
" y1 = Math.floor(y1) + 0.5;\n",
" var min_x = Math.min(x0, x1);\n",
" var min_y = Math.min(y0, y1);\n",
" var width = Math.abs(x1 - x0);\n",
" var height = Math.abs(y1 - y0);\n",
"\n",
" fig.rubberband_context.clearRect(\n",
" 0, 0, fig.canvas.width / mpl.ratio, fig.canvas.height / mpl.ratio);\n",
"\n",
" fig.rubberband_context.strokeRect(min_x, min_y, width, height);\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_figure_label = function(fig, msg) {\n",
" // Updates the figure title.\n",
" fig.header.textContent = msg['label'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_cursor = function(fig, msg) {\n",
" var cursor = msg['cursor'];\n",
" switch(cursor)\n",
" {\n",
" case 0:\n",
" cursor = 'pointer';\n",
" break;\n",
" case 1:\n",
" cursor = 'default';\n",
" break;\n",
" case 2:\n",
" cursor = 'crosshair';\n",
" break;\n",
" case 3:\n",
" cursor = 'move';\n",
" break;\n",
" }\n",
" fig.rubberband_canvas.style.cursor = cursor;\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_message = function(fig, msg) {\n",
" fig.message.textContent = msg['message'];\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_draw = function(fig, msg) {\n",
" // Request the server to send over a new figure.\n",
" fig.send_draw_message();\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_image_mode = function(fig, msg) {\n",
" fig.image_mode = msg['mode'];\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Called whenever the canvas gets updated.\n",
" this.send_message(\"ack\", {});\n",
"}\n",
"\n",
"// A function to construct a web socket function for onmessage handling.\n",
"// Called in the figure constructor.\n",
"mpl.figure.prototype._make_on_message_function = function(fig) {\n",
" return function socket_on_message(evt) {\n",
" if (evt.data instanceof Blob) {\n",
" /* FIXME: We get \"Resource interpreted as Image but\n",
" * transferred with MIME type text/plain:\" errors on\n",
" * Chrome. But how to set the MIME type? It doesn't seem\n",
" * to be part of the websocket stream */\n",
" evt.data.type = \"image/png\";\n",
"\n",
" /* Free the memory for the previous frames */\n",
" if (fig.imageObj.src) {\n",
" (window.URL || window.webkitURL).revokeObjectURL(\n",
" fig.imageObj.src);\n",
" }\n",
"\n",
" fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(\n",
" evt.data);\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
" else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == \"data:image/png;base64\") {\n",
" fig.imageObj.src = evt.data;\n",
" fig.updated_canvas_event();\n",
" fig.waiting = false;\n",
" return;\n",
" }\n",
"\n",
" var msg = JSON.parse(evt.data);\n",
" var msg_type = msg['type'];\n",
"\n",
" // Call the \"handle_{type}\" callback, which takes\n",
" // the figure and JSON message as its only arguments.\n",
" try {\n",
" var callback = fig[\"handle_\" + msg_type];\n",
" } catch (e) {\n",
" console.log(\"No handler for the '\" + msg_type + \"' message type: \", msg);\n",
" return;\n",
" }\n",
"\n",
" if (callback) {\n",
" try {\n",
" // console.log(\"Handling '\" + msg_type + \"' message: \", msg);\n",
" callback(fig, msg);\n",
" } catch (e) {\n",
" console.log(\"Exception inside the 'handler_\" + msg_type + \"' callback:\", e, e.stack, msg);\n",
" }\n",
" }\n",
" };\n",
"}\n",
"\n",
"// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas\n",
"mpl.findpos = function(e) {\n",
" //this section is from http://www.quirksmode.org/js/events_properties.html\n",
" var targ;\n",
" if (!e)\n",
" e = window.event;\n",
" if (e.target)\n",
" targ = e.target;\n",
" else if (e.srcElement)\n",
" targ = e.srcElement;\n",
" if (targ.nodeType == 3) // defeat Safari bug\n",
" targ = targ.parentNode;\n",
"\n",
" // jQuery normalizes the pageX and pageY\n",
" // pageX,Y are the mouse positions relative to the document\n",
" // offset() returns the position of the element relative to the document\n",
" var x = e.pageX - $(targ).offset().left;\n",
" var y = e.pageY - $(targ).offset().top;\n",
"\n",
" return {\"x\": x, \"y\": y};\n",
"};\n",
"\n",
"/*\n",
" * return a copy of an object with only non-object keys\n",
" * we need this to avoid circular references\n",
" * http://stackoverflow.com/a/24161582/3208463\n",
" */\n",
"function simpleKeys (original) {\n",
" return Object.keys(original).reduce(function (obj, key) {\n",
" if (typeof original[key] !== 'object')\n",
" obj[key] = original[key]\n",
" return obj;\n",
" }, {});\n",
"}\n",
"\n",
"mpl.figure.prototype.mouse_event = function(event, name) {\n",
" var canvas_pos = mpl.findpos(event)\n",
"\n",
" if (name === 'button_press')\n",
" {\n",
" this.canvas.focus();\n",
" this.canvas_div.focus();\n",
" }\n",
"\n",
" var x = canvas_pos.x * mpl.ratio;\n",
" var y = canvas_pos.y * mpl.ratio;\n",
"\n",
" this.send_message(name, {x: x, y: y, button: event.button,\n",
" step: event.step,\n",
" guiEvent: simpleKeys(event)});\n",
"\n",
" /* This prevents the web browser from automatically changing to\n",
" * the text insertion cursor when the button is pressed. We want\n",
" * to control all of the cursor setting manually through the\n",
" * 'cursor' event from matplotlib */\n",
" event.preventDefault();\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" // Handle any extra behaviour associated with a key event\n",
"}\n",
"\n",
"mpl.figure.prototype.key_event = function(event, name) {\n",
"\n",
" // Prevent repeat events\n",
" if (name == 'key_press')\n",
" {\n",
" if (event.which === this._key)\n",
" return;\n",
" else\n",
" this._key = event.which;\n",
" }\n",
" if (name == 'key_release')\n",
" this._key = null;\n",
"\n",
" var value = '';\n",
" if (event.ctrlKey && event.which != 17)\n",
" value += \"ctrl+\";\n",
" if (event.altKey && event.which != 18)\n",
" value += \"alt+\";\n",
" if (event.shiftKey && event.which != 16)\n",
" value += \"shift+\";\n",
"\n",
" value += 'k';\n",
" value += event.which.toString();\n",
"\n",
" this._key_event_extra(event, name);\n",
"\n",
" this.send_message(name, {key: value,\n",
" guiEvent: simpleKeys(event)});\n",
" return false;\n",
"}\n",
"\n",
"mpl.figure.prototype.toolbar_button_onclick = function(name) {\n",
" if (name == 'download') {\n",
" this.handle_save(this, null);\n",
" } else {\n",
" this.send_message(\"toolbar_button\", {name: name});\n",
" }\n",
"};\n",
"\n",
"mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {\n",
" this.message.textContent = tooltip;\n",
"};\n",
"mpl.toolbar_items = [[\"Home\", \"Reset original view\", \"fa fa-home icon-home\", \"home\"], [\"Back\", \"Back to previous view\", \"fa fa-arrow-left icon-arrow-left\", \"back\"], [\"Forward\", \"Forward to next view\", \"fa fa-arrow-right icon-arrow-right\", \"forward\"], [\"\", \"\", \"\", \"\"], [\"Pan\", \"Pan axes with left mouse, zoom with right\", \"fa fa-arrows icon-move\", \"pan\"], [\"Zoom\", \"Zoom to rectangle\", \"fa fa-square-o icon-check-empty\", \"zoom\"], [\"\", \"\", \"\", \"\"], [\"Download\", \"Download plot\", \"fa fa-floppy-o icon-save\", \"download\"]];\n",
"\n",
"mpl.extensions = [\"eps\", \"pdf\", \"png\", \"ps\", \"raw\", \"svg\"];\n",
"\n",
"mpl.default_extension = \"png\";var comm_websocket_adapter = function(comm) {\n",
" // Create a \"websocket\"-like object which calls the given IPython comm\n",
" // object with the appropriate methods. Currently this is a non binary\n",
" // socket, so there is still some room for performance tuning.\n",
" var ws = {};\n",
"\n",
" ws.close = function() {\n",
" comm.close()\n",
" };\n",
" ws.send = function(m) {\n",
" //console.log('sending', m);\n",
" comm.send(m);\n",
" };\n",
" // Register the callback with on_msg.\n",
" comm.on_msg(function(msg) {\n",
" //console.log('receiving', msg['content']['data'], msg);\n",
" // Pass the mpl event to the overridden (by mpl) onmessage function.\n",
" ws.onmessage(msg['content']['data'])\n",
" });\n",
" return ws;\n",
"}\n",
"\n",
"mpl.mpl_figure_comm = function(comm, msg) {\n",
" // This is the function which gets called when the mpl process\n",
" // starts-up an IPython Comm through the \"matplotlib\" channel.\n",
"\n",
" var id = msg.content.data.id;\n",
" // Get hold of the div created by the display call when the Comm\n",
" // socket was opened in Python.\n",
" var element = $(\"#\" + id);\n",
" var ws_proxy = comm_websocket_adapter(comm)\n",
"\n",
" function ondownload(figure, format) {\n",
" window.open(figure.imageObj.src);\n",
" }\n",
"\n",
" var fig = new mpl.figure(id, ws_proxy,\n",
" ondownload,\n",
" element.get(0));\n",
"\n",
" // Call onopen now - mpl needs it, as it is assuming we've passed it a real\n",
" // web socket which is closed, not our websocket->open comm proxy.\n",
" ws_proxy.onopen();\n",
"\n",
" fig.parent_element = element.get(0);\n",
" fig.cell_info = mpl.find_output_cell(\"\");\n",
" if (!fig.cell_info) {\n",
" console.error(\"Failed to find cell for figure\", id, fig);\n",
" return;\n",
" }\n",
"\n",
" var output_index = fig.cell_info[2]\n",
" var cell = fig.cell_info[0];\n",
"\n",
"};\n",
"\n",
"mpl.figure.prototype.handle_close = function(fig, msg) {\n",
" var width = fig.canvas.width/mpl.ratio\n",
" fig.root.unbind('remove')\n",
"\n",
" // Update the output cell to use the data from the current canvas.\n",
" fig.push_to_output();\n",
" var dataURL = fig.canvas.toDataURL();\n",
" // Re-enable the keyboard manager in IPython - without this line, in FF,\n",
" // the notebook keyboard shortcuts fail.\n",
" IPython.keyboard_manager.enable()\n",
" $(fig.parent_element).html('
');\n",
" fig.close_ws(fig, msg);\n",
"}\n",
"\n",
"mpl.figure.prototype.close_ws = function(fig, msg){\n",
" fig.send_message('closing', msg);\n",
" // fig.ws.close()\n",
"}\n",
"\n",
"mpl.figure.prototype.push_to_output = function(remove_interactive) {\n",
" // Turn the data on the canvas into data in the output cell.\n",
" var width = this.canvas.width/mpl.ratio\n",
" var dataURL = this.canvas.toDataURL();\n",
" this.cell_info[1]['text/html'] = '
';\n",
"}\n",
"\n",
"mpl.figure.prototype.updated_canvas_event = function() {\n",
" // Tell IPython that the notebook contents must change.\n",
" IPython.notebook.set_dirty(true);\n",
" this.send_message(\"ack\", {});\n",
" var fig = this;\n",
" // Wait a second, then push the new image to the DOM so\n",
" // that it is saved nicely (might be nice to debounce this).\n",
" setTimeout(function () { fig.push_to_output() }, 1000);\n",
"}\n",
"\n",
"mpl.figure.prototype._init_toolbar = function() {\n",
" var fig = this;\n",
"\n",
" var nav_element = $('');\n",
" nav_element.attr('style', 'width: 100%');\n",
" this.root.append(nav_element);\n",
"\n",
" // Define a callback function for later on.\n",
" function toolbar_event(event) {\n",
" return fig.toolbar_button_onclick(event['data']);\n",
" }\n",
" function toolbar_mouse_event(event) {\n",
" return fig.toolbar_button_onmouseover(event['data']);\n",
" }\n",
"\n",
" for(var toolbar_ind in mpl.toolbar_items){\n",
" var name = mpl.toolbar_items[toolbar_ind][0];\n",
" var tooltip = mpl.toolbar_items[toolbar_ind][1];\n",
" var image = mpl.toolbar_items[toolbar_ind][2];\n",
" var method_name = mpl.toolbar_items[toolbar_ind][3];\n",
"\n",
" if (!name) { continue; };\n",
"\n",
" var button = $('');\n",
" button.click(method_name, toolbar_event);\n",
" button.mouseover(tooltip, toolbar_mouse_event);\n",
" nav_element.append(button);\n",
" }\n",
"\n",
" // Add the status bar.\n",
" var status_bar = $('');\n",
" nav_element.append(status_bar);\n",
" this.message = status_bar[0];\n",
"\n",
" // Add the close button to the window.\n",
" var buttongrp = $('');\n",
" var button = $('');\n",
" button.click(function (evt) { fig.handle_close(fig, {}); } );\n",
" button.mouseover('Stop Interaction', toolbar_mouse_event);\n",
" buttongrp.append(button);\n",
" var titlebar = this.root.find($('.ui-dialog-titlebar'));\n",
" titlebar.prepend(buttongrp);\n",
"}\n",
"\n",
"mpl.figure.prototype._root_extra_style = function(el){\n",
" var fig = this\n",
" el.on(\"remove\", function(){\n",
"\tfig.close_ws(fig, {});\n",
" });\n",
"}\n",
"\n",
"mpl.figure.prototype._canvas_extra_style = function(el){\n",
" // this is important to make the div 'focusable\n",
" el.attr('tabindex', 0)\n",
" // reach out to IPython and tell the keyboard manager to turn it's self\n",
" // off when our div gets focus\n",
"\n",
" // location in version 3\n",
" if (IPython.notebook.keyboard_manager) {\n",
" IPython.notebook.keyboard_manager.register_events(el);\n",
" }\n",
" else {\n",
" // location in version 2\n",
" IPython.keyboard_manager.register_events(el);\n",
" }\n",
"\n",
"}\n",
"\n",
"mpl.figure.prototype._key_event_extra = function(event, name) {\n",
" var manager = IPython.notebook.keyboard_manager;\n",
" if (!manager)\n",
" manager = IPython.keyboard_manager;\n",
"\n",
" // Check for shift+enter\n",
" if (event.shiftKey && event.which == 13) {\n",
" this.canvas_div.blur();\n",
" // select the cell after this one\n",
" var index = IPython.notebook.find_cell_index(this.cell_info[0]);\n",
" IPython.notebook.select(index + 1);\n",
" }\n",
"}\n",
"\n",
"mpl.figure.prototype.handle_save = function(fig, msg) {\n",
" fig.ondownload(fig, null);\n",
"}\n",
"\n",
"\n",
"mpl.find_output_cell = function(html_output) {\n",
" // Return the cell and output element which can be found *uniquely* in the notebook.\n",
" // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n",
" // IPython event is triggered only after the cells have been serialised, which for\n",
" // our purposes (turning an active figure into a static one), is too late.\n",
" var cells = IPython.notebook.get_cells();\n",
" var ncells = cells.length;\n",
" for (var i=0; i= 3 moved mimebundle to data attribute of output\n",
" data = data.data;\n",
" }\n",
" if (data['text/html'] == html_output) {\n",
" return [cell, data, j];\n",
" }\n",
" }\n",
" }\n",
" }\n",
"}\n",
"\n",
"// Register the function which deals with the matplotlib target/channel.\n",
"// The kernel may be null if the page has been refreshed.\n",
"if (IPython.notebook.kernel != null) {\n",
" IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n",
"}\n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"