[图表]pyecharts-K线图
先来看代码:
import requests
from typing import List, Union
from pyecharts import options as opts
from pyecharts.charts import Kline, Line, Bar, Grid
def get_data():
response = requests.get(
url="https://echarts.apache.org/examples/data/asset/data/stock-DJI.json"
)
json_response = response.json()
# 解析数据
return split_data(data=json_response)
def split_data(data):
category_data = []
values = []
volumes = []
for i, tick in enumerate(data):
category_data.append(tick[0])
values.append(tick)
volumes.append([i, tick[4], 1 if tick[1] > tick[2] else -1])
return {"categoryData": category_data, "values": values, "volumes": volumes}
def calculate_ma(day_count: int, data):
result: List[Union[float, str]] = []
for i in range(len(data["values"])):
if i < day_count:
result.append("-")
continue
sum_total = 0.0
for j in range(day_count):
sum_total += float(data["values"][i - j][1])
result.append(abs(float("%.3f" % (sum_total / day_count))))
return result
def draw_charts():
kline_data = [data[1:-1] for data in chart_data["values"]]
kline = (
Kline()
.add_xaxis(xaxis_data=chart_data["categoryData"])
.add_yaxis(
series_name="Dow-Jones index",
y_axis=kline_data,
itemstyle_opts=opts.ItemStyleOpts(color="#ec0000", color0="#00da3c"),
)
.set_global_opts(
legend_opts=opts.LegendOpts(
is_show=False, pos_bottom=10, pos_left="center"
),
datazoom_opts=[
opts.DataZoomOpts(
is_show=False,
type_="inside",
xaxis_index=[0, 1],
range_start=98,
range_end=100,
),
opts.DataZoomOpts(
is_show=True,
xaxis_index=[0, 1],
type_="slider",
pos_top="85%",
range_start=98,
range_end=100,
),
],
yaxis_opts=opts.AxisOpts(
is_scale=True,
splitarea_opts=opts.SplitAreaOpts(
is_show=True, areastyle_opts=opts.AreaStyleOpts(opacity=1)
),
),
tooltip_opts=opts.TooltipOpts(
trigger="axis",
axis_pointer_type="cross",
background_color="rgba(245, 245, 245, 0.8)",
border_width=1,
border_color="#ccc",
textstyle_opts=opts.TextStyleOpts(color="#000"),
),
visualmap_opts=opts.VisualMapOpts(
is_show=False,
dimension=2,
series_index=5,
is_piecewise=True,
pieces=[
{"value": 1, "color": "#00da3c"},
{"value": -1, "color": "#ec0000"},
],
),
axispointer_opts=opts.AxisPointerOpts(
is_show=True,
link=[{"xAxisIndex": "all"}],
label=opts.LabelOpts(background_color="#777"),
),
brush_opts=opts.BrushOpts(
x_axis_index="all",
brush_link="all",
out_of_brush={"colorAlpha": 0.1},
brush_type="lineX",
),
)
)
line = (
Line()
.add_xaxis(xaxis_data=chart_data["categoryData"])
.add_yaxis(
series_name="MA5",
y_axis=calculate_ma(day_count=5, data=chart_data),
is_smooth=True,
is_hover_animation=False,
linestyle_opts=opts.LineStyleOpts(width=3, opacity=0.5),
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
series_name="MA10",
y_axis=calculate_ma(day_count=10, data=chart_data),
is_smooth=True,
is_hover_animation=False,
linestyle_opts=opts.LineStyleOpts(width=3, opacity=0.5),
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
series_name="MA20",
y_axis=calculate_ma(day_count=20, data=chart_data),
is_smooth=True,
is_hover_animation=False,
linestyle_opts=opts.LineStyleOpts(width=3, opacity=0.5),
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
series_name="MA30",
y_axis=calculate_ma(day_count=30, data=chart_data),
is_smooth=True,
is_hover_animation=False,
linestyle_opts=opts.LineStyleOpts(width=3, opacity=0.5),
label_opts=opts.LabelOpts(is_show=False),
)
.set_global_opts(xaxis_opts=opts.AxisOpts(type_="category"))
)
bar = (
Bar()
.add_xaxis(xaxis_data=chart_data["categoryData"])
.add_yaxis(
series_name="Volume",
y_axis=chart_data["volumes"],
xaxis_index=1,
yaxis_index=1,
label_opts=opts.LabelOpts(is_show=False),
)
.set_global_opts(
xaxis_opts=opts.AxisOpts(
type_="category",
is_scale=True,
grid_index=1,
boundary_gap=False,
axisline_opts=opts.AxisLineOpts(is_on_zero=False),
axistick_opts=opts.AxisTickOpts(is_show=False),
splitline_opts=opts.SplitLineOpts(is_show=False),
axislabel_opts=opts.LabelOpts(is_show=False),
split_number=20,
min_="dataMin",
max_="dataMax",
),
yaxis_opts=opts.AxisOpts(
grid_index=1,
is_scale=True,
split_number=2,
axislabel_opts=opts.LabelOpts(is_show=False),
axisline_opts=opts.AxisLineOpts(is_show=False),
axistick_opts=opts.AxisTickOpts(is_show=False),
splitline_opts=opts.SplitLineOpts(is_show=False),
),
legend_opts=opts.LegendOpts(is_show=False),
)
)
# Kline And Line
overlap_kline_line = kline.overlap(line)
# Grid Overlap + Bar
grid_chart = Grid(
init_opts=opts.InitOpts(
width="1000px",
height="800px",
animation_opts=opts.AnimationOpts(animation=False),
)
)
grid_chart.add(
overlap_kline_line,
grid_opts=opts.GridOpts(pos_left="10%", pos_right="8%", height="50%"),
)
grid_chart.add(
bar,
grid_opts=opts.GridOpts(
pos_left="10%", pos_right="8%", pos_top="63%", height="16%"
),
)
grid_chart.render("professional_kline_brush.html")
if __name__ == "__main__":
chart_data = get_data()
draw_charts()
再来看结果:
再来看不那么详细的解析:(太多了)
这段代码使用了Python中的一些模块来生成一个包含K线图、折线图和柱状图的可视化图表。以下是对代码的详细解析和代码注释:
import requests
from typing import List, Union
from pyecharts import options as opts
from pyecharts.charts import Kline, Line, Bar, Grid
导入了需要使用的模块,包括requests
用于发送HTTP请求,List
和Union
用于类型提示,以及Kline
、Line
、Bar
和Grid
模块用于生成图表。
def get_data():
response = requests.get(
url="https://echarts.apache.org/examples/data/asset/data/stock-DJI.json"
)
json_response = response.json()
# 解析数据
return split_data(data=json_response)
定义了一个函数get_data()
,该函数使用requests
模块发送HTTP请求获取数据。数据来自"https://echarts.apache.org/examples/data/asset/data/stock-DJI.json"这个URL。然后将获取到的JSON数据解析,并调用split_data()
函数对数据进行处理。
def split_data(data):
category_data = []
values = []
volumes = []
for i, tick in enumerate(data):
category_data.append(tick[0])
values.append(tick)
volumes.append([i, tick[4], 1 if tick[1] > tick[2] else -1])
return {"categoryData": category_data, "values": values, "volumes": volumes}
定义了一个函数split_data(data)
,该函数将获取到的JSON数据进行处理和分割。将时间序列、数据和成交量分别存储在category_data
、values
和volumes
变量中,然后将它们作为字典的键值返回。
def calculate_ma(day_count: int, data):
result: List[Union[float, str]] = []
for i in range(len(data["values"])):
if i < day_count:
result.append("-")
continue
sum_total = 0.0
for j in range(day_count):
sum_total += float(data["values"][i - j][1])
result.append(abs(float("%.3f" % (sum_total / day_count))))
return result
定义了一个函数calculate_ma(day_count, data)
,该函数用于计算移动平均线(Moving Average)。通过遍历数据并根据给定的天数计算移动平均线的值,然后将结果存储在result
列表中并返回。
def draw_charts():
kline_data = [data[1:-1] for data in chart_data["values"]]
kline = (
Kline()
.add_xaxis(xaxis_data=chart_data["categoryData"])
.add_yaxis(
series_name="Dow-Jones index",
y_axis=kline_data,
itemstyle_opts=opts.ItemStyleOpts(color="#ec0000", color0="#00da3c"),
)
.set_global_opts(
legend_opts=opts.LegendOpts(
is_show=False, pos_bottom=10, pos_left="center"
),
datazoom_opts=[
opts
.DataZoomOpts(
is_show=False,
type_="inside",
xaxis_index=[0, 1],
range_start=98,
range_end=100,
),
opts.DataZoomOpts(
is_show=True,
xaxis_index=[0, 1],
type_="slider",
pos_top="85%",
range_start=98,
range_end=100,
),
],
yaxis_opts=opts.AxisOpts(
is_scale=True,
splitarea_opts=opts.SplitAreaOpts(
is_show=True, areastyle_opts=opts.AreaStyleOpts(opacity=1)
),
),
tooltip_opts=opts.TooltipOpts(
trigger="axis",
axis_pointer_type="cross",
background_color="rgba(245, 245, 245, 0.8)",
border_width=1,
border_color="#ccc",
textstyle_opts=opts.TextStyleOpts(color="#000"),
),
visualmap_opts=opts.VisualMapOpts(
is_show=False,
dimension=2,
series_index=5,
is_piecewise=True,
pieces=[
{"value": 1, "color": "#00da3c"},
{"value": -1, "color": "#ec0000"},
],
),
axispointer_opts=opts.AxisPointerOpts(
is_show=True,
link=[{"xAxisIndex": "all"}],
label=opts.LabelOpts(background_color="#777"),
),
brush_opts=opts.BrushOpts(
x_axis_index="all",
brush_link="all",
out_of_brush={"colorAlpha": 0.1},
brush_type="lineX",
),
)
)
line = (
Line()
.add_xaxis(xaxis_data=chart_data["categoryData"])
.add_yaxis(
series_name="MA5",
y_axis=calculate_ma(day_count=5, data=chart_data),
is_smooth=True,
is_hover_animation=False,
linestyle_opts=opts.LineStyleOpts(width=3, opacity=0.5),
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
series_name="MA10",
y_axis=calculate_ma(day_count=10, data=chart_data),
is_smooth=True,
is_hover_animation=False,
linestyle_opts=opts.LineStyleOpts(width=3, opacity=0.5),
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
series_name="MA20",
y_axis=calculate_ma(day_count=20, data=chart_data),
is_smooth=True,
is_hover_animation=False,
linestyle_opts=opts.LineStyleOpts(width=3, opacity=0.5),
label_opts=opts.LabelOpts(is_show=False),
)
.add_yaxis(
series_name="MA30",
y_axis=calculate_ma(day_count=30, data=chart_data),
is_smooth=True,
is_hover_animation=False,
linestyle_opts=opts.LineStyleOpts(width=3, opacity=0.5),
label_opts=opts.LabelOpts(is_show=False),
)
.set_global_opts(xaxis_opts=opts.AxisOpts(type_="category"))
)
bar = (
Bar()
.add_xaxis(xaxis_data=chart_data["categoryData"])
.add_yaxis(
series_name="Volume",
y_axis=chart_data["volumes"],
xaxis_index=1,
yaxis_index=1,
label_opts=opts.LabelOpts(is_show=False),
)
.set_global_opts(
xaxis_opts=
opts.AxisOpts(
type_="category",
is_scale=True,
grid_index=1,
boundary_gap=False,
axisline_opts=opts.AxisLineOpts(is_on_zero=False),
axistick_opts=opts.AxisTickOpts(is_show=False),
splitline_opts=opts.SplitLineOpts(is_show=False),
axislabel_opts=opts.LabelOpts(is_show=False),
split_number=20,
min_="dataMin",
max_="dataMax",
),
yaxis_opts=opts.AxisOpts(
grid_index=1,
is_scale=True,
split_number=2,
axislabel_opts=opts.LabelOpts(is_show=False),
axisline_opts=opts.AxisLineOpts(is_show=False),
axistick_opts=opts.AxisTickOpts(is_show=False),
splitline_opts=opts.SplitLineOpts(is_show=False),
),
legend_opts=opts.LegendOpts(is_show=False),
)
)
创建了一个K线图实例kline
,并使用.add_xaxis()
方法设置x轴数据,使用.add_yaxis()
方法添加K线图的系列数据,其中系列名称为"Dow-Jones index",y轴数据为kline_data
,并设置了颜色样式。使用.set_global_opts()
方法设置图表的全局配置,包括图例、数据缩放、坐标轴、提示框、可视映射等。
创建了一个折线图实例line
,并使用.add_xaxis()
方法设置x轴数据,使用.add_yaxis()
方法添加折线图的系列数据,其中包括"MA5"、“MA10”、"MA20"和"MA30"这四个系列,y轴数据通过调用calculate_ma()
函数计算得到,设置了平滑曲线、不显示标签等样式,并使用.set_global_opts()
方法设置x轴的配置。
创建了一个柱状图实例bar
,并使用.add_xaxis()
方法设置x轴数据,使用.add_yaxis()
方法添加柱状图的系列数据,其中系列名称为"Volume",y轴数据为chart_data["volumes"]
,并设置了一些轴和坐标轴的配置。
overlap_kline_line = kline.overlap(line)
grid_chart = Grid(
init_opts=opts.InitOpts(
width="1000px",
height="800px",
animation_opts=opts.AnimationOpts(animation=False),
)
)
grid_chart.add(
overlap_kline_line,
grid_opts=opts.GridOpts(pos_left="10%", pos_right="8%", height="50%"),
)
grid_chart.add(
bar,
grid_opts=opts.GridOpts(
pos_left="10%", pos_right="8%", pos_top="63%", height="16%"
),
)
grid_chart.render("professional_kline_brush.html")
使用.overlap()
方法将K线图和折线图进行重叠叠加得到overlap_kline_line
。创建了一个网格图表grid_chart
,并设置了初始配置,包括宽度、高度和动画效果。使用.add()
方法将叠加后的图表overlap_kline_line
和柱状图bar
添加到网格图表中,并
设置了网格的位置和高度。最后调用.render()
方法将图表保存为HTML文件,文件名为"professional_kline_brush.html"。
以上就是这段代码的解析和注释说明。这段代码使用了pyecharts
库来生成包含K线图、折线图和柱状图的可视化图表,使用了HTTP请求获取数据,并对数据进行处理和分析,最终生成一个交互式的图表页面。
注:图表资源来源于:
pyecharts-gallery
本站只提供常用图表与其解析