def get_plot_base(self, _df, title_name='数据分布', subtitle_name=''): ''' plot line & bar info :param _df: :return: ''' bar = Bar() line = Line() bar.set_global_opts( title_opts=opts.TitleOpts(title=title_name, subtitle=subtitle_name), yaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts( formatter="{value}")), datazoom_opts=opts.DataZoomOpts(), # 滑动条 xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts( rotate=-15)), # label旋转 toolbox_opts=opts.ToolboxOpts(), ) xaxis = list(map(str, _df.index)) bar.add_xaxis(xaxis) line.add_xaxis(xaxis) for field in _df.columns: field = str(field) bar.add_yaxis(series_name=field, yaxis_data=_df[field].to_list(), is_selected=True) line.add_yaxis(series_name=field + self.series_name_add, y_axis=_df[field].to_list(), is_symbol_show=False) bar.overlap(line) return bar
def print_bar(self): bar = Bar(init_opts=opts.InitOpts(width='1080px', height='480px')) bar.add_xaxis(self.timedata) # category 是同系列直接的距离,gap是不同系列之间的距离 bar.add_yaxis('治愈人数', self.heal, gap='100%', label_opts=opts.LabelOpts(is_show=False), itemstyle_opts=opts.ItemStyleOpts(color='#90EE90')) if self.name == '湖北': bar.add_yaxis('死亡人数', self.dead, gap='100%', label_opts=opts.LabelOpts(is_show=False), itemstyle_opts=opts.ItemStyleOpts(color='#696969')) # 设置全局变量:x轴标签倾斜度,html主标题 bar.set_global_opts(datazoom_opts=[ opts.DataZoomOpts(), opts.DataZoomOpts(type_='inside') ], toolbox_opts=opts.ToolboxOpts(), xaxis_opts=opts.AxisOpts(name_rotate=-15), title_opts=opts.TitleOpts(self.name, subtitle='数据来自inews')) line = Line() line.add_xaxis(self.timedata) line.add_yaxis('确诊人数', self.confirm, label_opts=opts.LabelOpts(is_show=False), itemstyle_opts=opts.ItemStyleOpts(color='#F08080')) print(self.name + '.html', '已成功生成到', os.getcwd()) # 在bar的基础上画line bar.overlap(line).render(self.name + '.html')
def workarea_salary_chart(df): # 转换类型为浮点型 df.low_salary, df.high_salary = df.low_salary.astype( float), df.high_salary.astype(float) # 分别求各地区平均最高薪资, 平均最低薪资 salary = df.groupby('workarea', as_index=False)[['low_salary', 'high_salary' ]].mean() # 分别求各地区的岗位数量,并降序排列 print(salary) workarea = df.groupby('workarea', as_index=False)['name'].count().sort_values( 'name', ascending=False) print(workarea) workarea = pd.merge(workarea, salary, how='left', on='workarea') # 合并数据表 print(workarea) workarea = workarea.head(20) # 用前20名进行绘图 grid = Grid() bar = Bar() grid.theme = themes line = Line() line1 = Line() bar.add_xaxis(workarea.workarea.tolist()) bar.add_yaxis("岗位需求量", workarea.name.tolist()) bar.set_global_opts( title_opts=opts.TitleOpts( title="岗位需求量排名前20地区的平均薪资水平状况", title_link='./chart/workarea_salary_chart.html', title_target='blank', pos_left='left', ), tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="cross", is_show=True), # 交叉指向工具 legend_opts=opts.LegendOpts(pos_left="80%", orient="vertical", pos_top="3%"), ) # bar.set_series_opts(is_show=True, position='rightTop') print((workarea.name).tolist()) print((round(workarea.high_salary * 1000)).tolist()) # 在bar上增加Y轴,在line图上选择对应的轴向 line.add_xaxis(workarea.workarea.tolist()) line.add_yaxis("平均最高薪资", (round(workarea.high_salary * 1000)).tolist(), yaxis_index=0) line1.add_xaxis(workarea.workarea.tolist()) line1.add_yaxis("平均最低薪资", (round(workarea.low_salary * 1000)).tolist(), yaxis_index=0) # 把line添加到bar上 bar.overlap(line) bar.overlap(line1) # 这里如果不需要grid也可以,直接设置bar的格式,然后显示bar即可 #bar.render_notebook() grid.add(chart=bar, grid_opts=opts.GridOpts(), is_control_axis_index=True) # grid.render("./chart/workarea_salary_chart.html") return grid
def paintGraph(contestInfo, starttime='2017-09', endtime='2020-07'): # 先根据指定的起始日期和截止日期构造需要的数据 x, cf, ac, nc, jsk, total = [], [], [], [], [], [] for key, value in sorted(contestInfo.items()): if key >= starttime and key <= endtime: x.append(key) cf.append({'value': value.get('cf', 0)}) ac.append({'value': value.get('ac', 0)}) nc.append({'value': value.get('nc', 0)}) jsk.append({'value': value.get('jsk', 0)}) total.append(value.get('total', 0)) # print(total) # 绘制图表 bar = Bar( init_opts=opts.InitOpts(theme=ThemeType.LIGHT, page_title='各年月比赛数量统计')) bar.set_global_opts(title_opts=opts.TitleOpts(title='各年月比赛数量统计'), xaxis_opts=opts.AxisOpts(name='比赛年月'), yaxis_opts=opts.AxisOpts(name='比赛数量统计')) bar.add_xaxis(x) bar.add_yaxis("CodeForces", cf, stack="stack1", category_gap="50%") bar.add_yaxis("NowCoder", nc, stack="stack1", category_gap="50%") bar.add_yaxis("AtCoder", ac, stack="stack1", category_gap="50%") bar.add_yaxis("计蒜客", jsk, stack="stack1", category_gap="50%") bar.set_series_opts(label_opts=opts.LabelOpts( position="inside", formatter=JsCode( "function(x){return x.data.value ? Number(x.data.value) : '';}"), )) line = Line() line.set_global_opts( tooltip_opts=opts.TooltipOpts(is_show=False), xaxis_opts=opts.AxisOpts(type_="category"), yaxis_opts=opts.AxisOpts( type_="value", axistick_opts=opts.AxisTickOpts(is_show=True), splitline_opts=opts.SplitLineOpts(is_show=True), ), ) line.add_xaxis(xaxis_data=x) line.add_yaxis( series_name="total", y_axis=total, symbol="Circle", is_symbol_show=True, label_opts=opts.LabelOpts(is_show=True), ) # 将柱状图与折线图一起输出到html文件中 bar.overlap(line).render('acmersite02.html')
def workhour_get(): p = WorkhourInfo() # 获取最近的12月 df = p.df.dropna()[-12:] xdata = df['月份'].tolist() # fig = Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT)) fig = Bar() fig.add_xaxis(xdata) fig.add_yaxis('总投入', df['实际投入工时'].tolist(), label_opts=opts.LabelOpts(position='inside')) for v in df.columns[6:]: fig.add_yaxis(v, df[v].tolist(), stack='detail', is_selected=False, label_opts=opts.LabelOpts(is_show=False)) fig.set_global_opts( title_opts=opts.TitleOpts(title="最近12月工时投入"), tooltip_opts=opts.TooltipOpts(is_show=True, trigger="axis", axis_pointer_type="shadow"), yaxis_opts=opts.AxisOpts(name='工时'), ) #""" df['投入总工时比率'] = (df['投入总工时比率'] * 100).round(0) maxratio = df['投入总工时比率'].max() maxratio = 100 if maxratio <= 100 else maxratio ratio = df['投入总工时比率'].tolist() line = Line() line.add_xaxis(xdata) line.add_yaxis('投入工时率', ratio, yaxis_index=1) fig.extend_axis(yaxis=opts.AxisOpts(name="投入工时率", type_="value", min_=0, max_=maxratio, axislabel_opts=opts.LabelOpts( formatter="{value} %"))) fig.overlap(line) #""" return fig.dump_options_with_quotes()
def draw_balance_bar(xaxis, yaxis, difference=None, title="消费统计", markline=None, width=2000) -> Bar: """ x = [月_日, 月_日, 月_日, ....] y = [(title1, [num1, num2, num3, num4, ...]), (title2, [num1, num2, num3, num4, ...])] :param difference: 差值 (比如:收入100,消费80,差值就是20) : ['title', [1,2,3,4]] :param xaxis: x轴 :param yaxis: y轴 :param title: 标题 :param markline: 标记辅助线 :param width: 宽 :return: Bar """ bar = Bar() bar.add_xaxis(xaxis) for name, axis in yaxis: bar.add_yaxis(name, axis, category_gap="20%", gap="0%") bar.set_global_opts(title_opts=opts.TitleOpts(title=title, ), datazoom_opts=[ opts.DataZoomOpts(range_start=0, range_end=100), opts.DataZoomOpts(type_="inside") ], tooltip_opts=opts.TooltipOpts( trigger='axis', axis_pointer_type='shadow')) bar.set_series_opts(label_opts=opts.LabelOpts(is_show=False)) if difference: name, diff_yaxis = difference line = Line().add_xaxis(xaxis).add_yaxis( name, diff_yaxis, symbol_size=15, z_level=1, is_symbol_show=False, ) bar.overlap(line) if markline is not None: bar.set_series_opts(markline_opts=opts.MarkLineOpts( data=[opts.MarkLineItem(y=markline, name='预算')])) return bar
def dsp_her(): # 显示遗传力 # page = Page(layout=Page.DraggablePageLayout) import xlrd # file = "breeding.xlsx" f1 = xlrd.open_workbook(file) sheet1 = f1.sheet_by_name('Sheet1') lst = her(file) # 接收计算的遗传力 y = [] colorArr = [ '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ] for i in range(len(lst)): color = "#" for j in range(6): color += colorArr[random.randint(0, 14)] y.append( opts.BarItem( value=lst[i], itemstyle_opts=opts.ItemStyleOpts(color=str(color)), # itemstyle_opts=opts.ItemStyleOpts(color=color[i]) )) x_ax = [] y_ax = [] start = load_profile()[0] end = load_profile()[1] for i in range(start, end + 1): x_ax.append(sheet1.cell_value(0, i)) bar = Bar(init_opts=opts.InitOpts( #bg_color='rgba(155,250,205,0.2)', width="1800px", height="800px")) bar.set_colors(["#FF6347", "black"]) # FF6347 bar.add_xaxis(x_ax) bar.add_yaxis("遗传力", y, category_gap="60%") bar.set_series_opts( label_opts=opts.LabelOpts(is_show=False), markpoint_opts=opts.MarkPointOpts( data=[opts.MarkPointItem(type_="max", name="最大值")])) # bar.add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49]) bar.set_global_opts(title_opts=opts.TitleOpts(title="显示已有数据遗传力")) for i in range(sheet1.nrows - 1): y_ax.append(i) line = Line(init_opts=opts.InitOpts(width="1800px", height="800px")) line.add_xaxis(y_ax) line.add_yaxis(series_name="", y_axis=lst, label_opts=opts.LabelOpts(is_show=True)) picture = bar.overlap(line) return render_template("display.html", picture_options=picture.dump_options())
def paint_bar_stack_with_line(self, x: list, children: dict, parents: dict, sub_title: str): for (parent_name, unit), item in children.items(): bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.MACARONS)) bar.add_xaxis(x) line = Line() line.add_xaxis(x) child_names = [] for child_name, data, overall in item: bar.add_yaxis(child_name, data, stack='stack1') line.add_yaxis(f'{child_name}占比', overall, yaxis_index=1) child_names.append(child_name) bar.add_yaxis(parent_name, parents[parent_name], stack='stack1', yaxis_index=0) bar.set_global_opts( title_opts=opts.TitleOpts(title=','.join(child_names), subtitle=sub_title, pos_left='5%'), legend_opts=opts.LegendOpts(pos_bottom='0')) bar.set_series_opts(label_opts=opts.LabelOpts(is_show=False), tooltip_opts=opts.TooltipOpts( formatter=f'{{b}}年{{a}}:{{c}}{unit}'), itemstyle_opts=opts.ItemStyleOpts(opacity=0.5)) bar.extend_axis(yaxis=opts.AxisOpts( type_='value', name='所占比例', min_=0, max_=1, position='right', splitline_opts=opts.SplitLineOpts( is_show=True, linestyle_opts=opts.LineStyleOpts( opacity=1)))) bar.overlap(line) yield bar
def kline_pro(kline: List[dict], fx: List[dict] = None, xd=None, bs: List[dict] = None, title: str = "缠中说禅K线分析", width: str = "1400px", height: str = '580px') -> Grid: """绘制缠中说禅K线分析结果 :param kline: K线 :param fx: 分型识别结果 :param bi: 笔识别结果 :param xd: 线段识别结果 :param zs: 中枢 :param bs: 买卖点 :param title: 图表标题 :param width: 图表宽度 :param height: 图表高度 :return: 用Grid组合好的图表 """ # 配置项设置 # ------------------------------------------------------------------------------------------------------------------ bg_color = "#1f212d" # 背景 up_color = "#F9293E" down_color = "#00aa3b" init_opts = opts.InitOpts(bg_color=bg_color, width=width, height=height, animation_opts=opts.AnimationOpts(False)) title_opts = opts.TitleOpts( title=title, pos_top="1%", title_textstyle_opts=opts.TextStyleOpts(color=up_color, font_size=20), subtitle_textstyle_opts=opts.TextStyleOpts(color=down_color, font_size=12)) label_not_show_opts = opts.LabelOpts(is_show=False) legend_not_show_opts = opts.LegendOpts(is_show=False) red_item_style = opts.ItemStyleOpts(color=up_color) green_item_style = opts.ItemStyleOpts(color=down_color) k_style_opts = opts.ItemStyleOpts(color=up_color, color0=down_color, border_color=up_color, border_color0=down_color, opacity=0.8) legend_opts = opts.LegendOpts(is_show=True, pos_top="1%", pos_left="30%", item_width=14, item_height=8, textstyle_opts=opts.TextStyleOpts( font_size=12, color="#0e99e2")) brush_opts = opts.BrushOpts(tool_box=["rect", "polygon", "keep", "clear"], x_axis_index="all", brush_link="all", out_of_brush={"colorAlpha": 0.1}, brush_type="lineX") axis_pointer_opts = opts.AxisPointerOpts(is_show=True, link=[{ "xAxisIndex": "all" }]) range_start = int(100 - 216 / len(kline) * 100) dz_inside = opts.DataZoomOpts(False, "inside", xaxis_index=[0, 1, 2], range_start=range_start, range_end=100) dz_slider = opts.DataZoomOpts(True, "slider", xaxis_index=[0, 1, 2], pos_top="96%", pos_bottom="0%", range_start=range_start, range_end=100) yaxis_opts = opts.AxisOpts(is_scale=True, axislabel_opts=opts.LabelOpts( color="#c7c7c7", font_size=8, position="inside")) grid0_xaxis_opts = opts.AxisOpts( type_="category", grid_index=0, axislabel_opts=label_not_show_opts, split_number=20, min_="dataMin", max_="dataMax", is_scale=True, boundary_gap=False, axisline_opts=opts.AxisLineOpts(is_on_zero=False)) tool_tip_opts = opts.TooltipOpts( trigger="axis", axis_pointer_type="cross", background_color="rgba(245, 245, 245, 0.8)", border_width=1, border_color="#ccc", position=JsCode(""" function (pos, params, el, elRect, size) { var obj = {top: 10}; obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 30; return obj; } """), textstyle_opts=opts.TextStyleOpts(color="#000"), ) # 数据预处理 # ------------------------------------------------------------------------------------------------------------------ # dts = [x.get('dt', x['date']) for x in kline] try: dts = [x['date'] for x in kline] except: dts = [x['dt'] for x in kline] # k_data = [[x['open'], x['close'], x['low'], x['high']] for x in kline] k_data = [ opts.CandleStickItem( name=i, value=[x['open'], x['close'], x['low'], x['high']]) for i, x in enumerate(kline) ] vol = [] for i, row in enumerate(kline): item_style = red_item_style if row['close'] > row[ 'open'] else green_item_style bar = opts.BarItem(name=i, value=row['volume'], itemstyle_opts=item_style, label_opts=label_not_show_opts) vol.append(bar) close = np.array([x['close'] for x in kline], dtype=np.double) diff, dea, macd = MACD(close) ma5 = SMA(close, timeperiod=5) ma34 = SMA(close, timeperiod=34) ma55 = SMA(close, timeperiod=55) ma233 = SMA(close, timeperiod=233) macd_bar = [] for i, v in enumerate(macd.tolist()): item_style = red_item_style if v > 0 else green_item_style bar = opts.BarItem(name=i, value=round(v, 4), itemstyle_opts=item_style, label_opts=label_not_show_opts) macd_bar.append(bar) diff = diff.round(4) dea = dea.round(4) # K 线主图 # ------------------------------------------------------------------------------------------------------------------ chart_k = Kline() chart_k.add_xaxis(xaxis_data=dts) chart_k.add_yaxis(series_name="Kline", y_axis=k_data, itemstyle_opts=k_style_opts) chart_k.set_global_opts(legend_opts=legend_opts, datazoom_opts=[dz_inside, dz_slider], yaxis_opts=yaxis_opts, tooltip_opts=tool_tip_opts, axispointer_opts=axis_pointer_opts, brush_opts=brush_opts, title_opts=title_opts, xaxis_opts=grid0_xaxis_opts) if xd: index = 0 zs_colors = [ "yellow", "white", '#f034c1', "#7944b7", "#468b58", "#c17f2f", "#9EA0A1" ] data = [] temp_xd = xd while temp_xd: zs_color = zs_colors[index % len(zs_colors)] data = data + [ opts.MarkAreaItem( name='XD{}'.format(index), x=(x['xd_list'][0]['date'], x['xd_list'][-1]['date']), y=(x['ZG']['value'], x['ZD']['value']), label_opts=opts.LabelOpts(color=zs_color), itemstyle_opts=opts.ItemStyleOpts( color=zs_color, opacity=0.2, )) for x in temp_xd.zs_list ] temp_xd = temp_xd.next index = index + 1 chart_k.set_series_opts( markarea_opts=opts.MarkAreaOpts(is_silent=True, data=data)) # 均线图 # ------------------------------------------------------------------------------------------------------------------ chart_ma = Line() chart_ma.add_xaxis(xaxis_data=dts) ma_keys = {"MA5": ma5, "MA34": ma34, "MA55": ma55, "MA233": ma233} ma_colors = ["#39afe6", "#da6ee8", "#A02128", "#00940b"] for i, (name, ma) in enumerate(ma_keys.items()): chart_ma.add_yaxis(series_name=name, y_axis=ma, is_smooth=True, is_selected=False, symbol_size=0, label_opts=label_not_show_opts, linestyle_opts=opts.LineStyleOpts( opacity=0.8, width=1.0, color=ma_colors[i])) chart_ma.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) chart_k = chart_k.overlap(chart_ma) # 缠论结果 # ------------------------------------------------------------------------------------------------------------------ if fx: try: fx_dts = [x['date'] for x in fx] except: fx_dts = [x['dt'] for x in fx] fx_val = [x['value'] for x in fx] chart_fx = Scatter() chart_fx.add_xaxis(fx_dts) chart_fx.add_yaxis(series_name="FX", y_axis=fx_val, is_selected=False, symbol="circle", symbol_size=6, label_opts=label_not_show_opts, itemstyle_opts=opts.ItemStyleOpts( color="rgba(152, 147, 193, 1.0)", )) chart_fx.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) chart_k = chart_k.overlap(chart_fx) if xd: index = 0 xd_colors = zs_colors while xd: xd_dts = [x['date'] for x in xd] xd_val = [x['value'] for x in xd] chart_xd = Line() chart_xd.add_xaxis(xd_dts) xd_color = xd_colors[index % len(xd_colors)] chart_xd.add_yaxis( series_name="XD{}".format(index), y_axis=xd_val, is_selected=True, symbol="triangle", symbol_size=10, linestyle_opts=opts.LineStyleOpts(color=xd_color, width=index + 1, type_="solid"), itemstyle_opts=opts.ItemStyleOpts(color=xd_color)) chart_xd.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) chart_k = chart_k.overlap(chart_xd) xd = xd.next index = index + 1 if bs: b_dts = [x['date'] for x in bs if x['bs'] == 'buy'] if len(b_dts) > 0: b_val = [x['value'] for x in bs if x['bs'] == 'buy'] chart_b = Scatter() chart_b.add_xaxis(b_dts) chart_b.add_yaxis(series_name="BUY", y_axis=b_val, is_selected=False, symbol="arrow", symbol_size=8, itemstyle_opts=opts.ItemStyleOpts( color="#f31e1e", )) chart_b.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) chart_k = chart_k.overlap(chart_b) s_dts = [x['date'] for x in bs if x['bs'] == 'sell'] if len(s_dts) > 0: s_val = [x['value'] for x in bs if x['bs'] == 'sell'] chart_s = Scatter() chart_s.add_xaxis(s_dts) chart_s.add_yaxis(series_name="SELL", y_axis=s_val, is_selected=False, symbol="pin", symbol_size=12, itemstyle_opts=opts.ItemStyleOpts( color="#45b97d", )) chart_s.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) chart_k = chart_k.overlap(chart_s) # 成交量图 # ------------------------------------------------------------------------------------------------------------------ chart_vol = Bar() chart_vol.add_xaxis(dts) chart_vol.add_yaxis(series_name="Volume", y_axis=vol, bar_width='60%') chart_vol.set_global_opts( xaxis_opts=opts.AxisOpts( type_="category", grid_index=1, axislabel_opts=opts.LabelOpts(is_show=True, font_size=8, color="#9b9da9"), ), yaxis_opts=yaxis_opts, legend_opts=legend_not_show_opts, ) # MACD图 # ------------------------------------------------------------------------------------------------------------------ chart_macd = Bar() chart_macd.add_xaxis(dts) chart_macd.add_yaxis(series_name="MACD", y_axis=macd_bar, bar_width='60%') chart_macd.set_global_opts( xaxis_opts=opts.AxisOpts( type_="category", grid_index=2, axislabel_opts=opts.LabelOpts(is_show=False), ), yaxis_opts=opts.AxisOpts( grid_index=2, split_number=4, 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=True, color="#c7c7c7"), ), legend_opts=opts.LegendOpts(is_show=False), ) line = Line() line.add_xaxis(dts) line.add_yaxis(series_name="DIFF", y_axis=diff, label_opts=label_not_show_opts, is_symbol_show=False, linestyle_opts=opts.LineStyleOpts(opacity=0.8, width=1.0, color="#da6ee8")) line.add_yaxis(series_name="DEA", y_axis=dea, label_opts=label_not_show_opts, is_symbol_show=False, linestyle_opts=opts.LineStyleOpts(opacity=0.8, width=1.0, color="#39afe6")) chart_macd = chart_macd.overlap(line) grid0_opts = opts.GridOpts(pos_left="0%", pos_right="1%", pos_top="12%", height="58%") grid1_opts = opts.GridOpts(pos_left="0%", pos_right="1%", pos_top="74%", height="8%") grid2_opts = opts.GridOpts(pos_left="0%", pos_right="1%", pos_top="86%", height="10%") grid_chart = Grid(init_opts) grid_chart.add(chart_k, grid_opts=grid0_opts) grid_chart.add(chart_vol, grid_opts=grid1_opts) grid_chart.add(chart_macd, grid_opts=grid2_opts) return grid_chart
line.set_global_opts() .add_xaxis(xaxis_data=x_data) .add_yaxis( series_name="总数", y_axis=y3_data, symbol="circle", symbol_size=10, is_symbol_show=True, itemstyle_opts=opts.ItemStyleOpts( color="rgba(252,230,48,1)", border_width=0, ), label_opts=opts.LabelOpts( is_show=True, position="top" ), linestyle_opts=opts.LineStyleOpts( width=2, ) ) ) bar.overlap(line) ( Grid(opts.InitOpts(bg_color="#344b58")) .add( bar, opts.GridOpts() ) ).render("pyecharts_bar.html")
def echarts_stackbar( df, # 传入数据df,应该是一个行索引为date的时间序列面板数据 df_gr=None, # 传入同比增长率df,可以没有 datatype="ABS", # 主Y轴形式是绝对值,增长率还是份额,用来确定一些标签格式,默认为绝对值 ) -> Bar: axislabel_format = "{value}" # 主Y轴默认格式 max = df[df > 0].sum(axis=1).max() # 主Y轴默认最大值 min = df[df <= 0].sum(axis=1).min() # 主Y轴默认最小值 if datatype in ["SHARE", "GR"]: # 如果主数据不是绝对值形式而是份额或增长率如何处理 df = df.multiply(100).round(2) axislabel_format = "{value}%" max = 100 min = 0 if df_gr is not None: df_gr = df_gr.multiply(100).round(2) # 如果有同比增长率,原始数*100呈现 if df.empty is False: stackbar = Bar().add_xaxis(df.index.tolist()) for i, item in enumerate(df.columns): # 预留的枚举,这个方法以后可以根据输入对象不同从单一柱状图变成堆积柱状图 stackbar.add_yaxis( item, df[item].values.tolist(), stack="总量", label_opts=opts.LabelOpts(is_show=False), z_level=1, ) # .add_yaxis(series_name=df.index[-5].strftime("%Y-%m"), # yaxis_data=df_ya.values.tolist(), # stack='总量', # label_opts=opts.LabelOpts(is_show=False) # ) # .add_yaxis(series_name=df.index[-1].strftime("%Y-%m")+' vs '+df.index[-5].strftime("%Y-%m"), # yaxis_data=df_diff.values.tolist(), # stack='总量', # label_opts=opts.LabelOpts(is_show=False) # ) if df_gr is not None: # 如果有同比增长率数据则加入次Y轴 stackbar.extend_axis( yaxis=opts.AxisOpts( name=df_gr.columns.astype("str")[0], type_="value", axislabel_opts=opts.LabelOpts(formatter="{value}%"), ) ) stackbar.set_global_opts( legend_opts=opts.LegendOpts(pos_top="5%", pos_left="10%", pos_right="60%"), # toolbox_opts=opts.ToolboxOpts(is_show=True), tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="cross",), xaxis_opts=opts.AxisOpts( type_="category", boundary_gap=True, axislabel_opts=opts.LabelOpts(rotate=90), # x轴标签方向rotate有时能解决拥挤显示不全的问题 splitline_opts=opts.SplitLineOpts( is_show=False, linestyle_opts=opts.LineStyleOpts(type_="dotted", opacity=0.5,), ), ), yaxis_opts=opts.AxisOpts( max_=max, min_=min, type_="value", axislabel_opts=opts.LabelOpts(formatter=axislabel_format), # axistick_opts=opts.AxisTickOpts(is_show=True), splitline_opts=opts.SplitLineOpts( is_show=True, linestyle_opts=opts.LineStyleOpts(type_="dotted", opacity=0.5,), ), ), ) if df_gr is not None: line = ( Line() .add_xaxis(xaxis_data=df_gr.index.tolist()) .add_yaxis( series_name=df_gr.columns.astype("str")[0], yaxis_index=1, y_axis=df_gr.values.tolist(), label_opts=opts.LabelOpts(is_show=False), linestyle_opts=opts.LineStyleOpts(width=3), symbol_size=8, itemstyle_opts=opts.ItemStyleOpts( border_width=1, border_color="", border_color0="white" ), z_level=2, ) ) else: stackbar = Bar() if df_gr is not None: return stackbar.overlap(line) # 如果有次坐标轴最后要用overlap方法组合 else: return stackbar
def kline_pro(kline: List[dict], ma: List[dict], macd: List[dict], fx: List[dict] = None, bi: List[dict] = None, xd: List[dict] = None, bs: List[dict] = None, title: str = "缠中说禅K线分析", width: str = "1200px", height: str = '680px') -> Grid: """绘制缠中说禅K线分析结果 :param kline: K线 :param ma: 均线 :param macd: MACD :param fx: 分型识别结果 :param bi: 笔识别结果 :param xd: 线段识别结果 :param bs: 买卖点 :param title: 图表标题 :param width: 图表宽度 :param height: 图表高度 :return: 用Grid组合好的图表 """ # 配置项设置 # ------------------------------------------------------------------------------------------------------------------ bg_color = "#1f212d" # 背景 up_color = "#F9293E" down_color = "#00aa3b" init_opts = opts.InitOpts(bg_color=bg_color, width=width, height=height, animation_opts=opts.AnimationOpts(False)) title_opts = opts.TitleOpts( title=title, pos_top="1%", title_textstyle_opts=opts.TextStyleOpts(color=up_color, font_size=20), subtitle_textstyle_opts=opts.TextStyleOpts(color=down_color, font_size=12)) label_not_show_opts = opts.LabelOpts(is_show=False) legend_not_show_opts = opts.LegendOpts(is_show=False) red_item_style = opts.ItemStyleOpts(color=up_color) green_item_style = opts.ItemStyleOpts(color=down_color) k_style_opts = opts.ItemStyleOpts(color=up_color, color0=down_color, border_color=up_color, border_color0=down_color, opacity=0.8) legend_opts = opts.LegendOpts(is_show=True, pos_top="1%", pos_left="30%", item_width=14, item_height=8, textstyle_opts=opts.TextStyleOpts( font_size=12, color="#0e99e2")) brush_opts = opts.BrushOpts(tool_box=["rect", "polygon", "keep", "clear"], x_axis_index="all", brush_link="all", out_of_brush={"colorAlpha": 0.1}, brush_type="lineX") axis_pointer_opts = opts.AxisPointerOpts(is_show=True, link=[{ "xAxisIndex": "all" }]) dz_inside = opts.DataZoomOpts(False, "inside", xaxis_index=[0, 1, 2]) dz_slider = opts.DataZoomOpts(True, "slider", xaxis_index=[0, 1, 2], pos_top="96%", pos_bottom="0%") yaxis_opts = opts.AxisOpts(is_scale=True, axislabel_opts=opts.LabelOpts( color="#c7c7c7", font_size=8, position="inside")) grid0_xaxis_opts = opts.AxisOpts( type_="category", grid_index=0, axislabel_opts=label_not_show_opts, split_number=20, min_="dataMin", max_="dataMax", is_scale=True, boundary_gap=False, axisline_opts=opts.AxisLineOpts(is_on_zero=False)) tool_tip_opts = opts.TooltipOpts( trigger="axis", axis_pointer_type="cross", background_color="rgba(245, 245, 245, 0.8)", border_width=1, border_color="#ccc", position=JsCode(""" function (pos, params, el, elRect, size) { var obj = {top: 10}; obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 30; return obj; } """), textstyle_opts=opts.TextStyleOpts(color="#000"), ) # 数据预处理 # ------------------------------------------------------------------------------------------------------------------ dts = [x['dt'] for x in kline] k_data = [[x['open'], x['close'], x['low'], x['high']] for x in kline] vol = [] for row in kline: item_style = red_item_style if row['close'] > row[ 'open'] else green_item_style bar = opts.BarItem(value=row['vol'], itemstyle_opts=item_style, label_opts=label_not_show_opts) vol.append(bar) macd_bar = [] for row in macd: item_style = red_item_style if row['macd'] > 0 else green_item_style bar = opts.BarItem(value=round(row['macd'], 4), itemstyle_opts=item_style, label_opts=label_not_show_opts) macd_bar.append(bar) diff = [round(x['diff'], 4) for x in macd] dea = [round(x['dea'], 4) for x in macd] # K 线主图 # ------------------------------------------------------------------------------------------------------------------ chart_k = Kline() chart_k.add_xaxis(xaxis_data=dts) chart_k.add_yaxis(series_name="Kline", y_axis=k_data, itemstyle_opts=k_style_opts) chart_k.set_global_opts(legend_opts=legend_opts, datazoom_opts=[dz_inside, dz_slider], yaxis_opts=yaxis_opts, tooltip_opts=tool_tip_opts, axispointer_opts=axis_pointer_opts, brush_opts=brush_opts, title_opts=title_opts, xaxis_opts=grid0_xaxis_opts) # 均线图 # ------------------------------------------------------------------------------------------------------------------ chart_ma = Line() chart_ma.add_xaxis(xaxis_data=dts) ma_keys = [x for x in ma[0].keys() if "ma" in x][:3] ma_colors = ["#39afe6", "#da6ee8", "#00940b"] for i, k in enumerate(ma_keys): y_data = [x[k] for x in ma] chart_ma.add_yaxis(series_name=k.upper(), y_axis=y_data, is_smooth=True, is_selected=False, symbol_size=0, label_opts=label_not_show_opts, linestyle_opts=opts.LineStyleOpts( opacity=0.8, width=1.0, color=ma_colors[i])) chart_ma.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) chart_k = chart_k.overlap(chart_ma) # 缠论结果 # ------------------------------------------------------------------------------------------------------------------ if fx: fx_dts = [x['dt'] for x in fx] fx_val = [x['fx'] for x in fx] chart_fx = Scatter() chart_fx.add_xaxis(fx_dts) chart_fx.add_yaxis(series_name="FX", y_axis=fx_val, is_selected=False, symbol="circle", symbol_size=6, label_opts=label_not_show_opts, itemstyle_opts=opts.ItemStyleOpts( color="rgba(152, 147, 193, 1.0)", )) chart_fx.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) chart_k = chart_k.overlap(chart_fx) if bi: bi_dts = [x['dt'] for x in bi] bi_val = [x['bi'] for x in bi] chart_bi = Scatter() chart_bi.add_xaxis(bi_dts) chart_bi.add_yaxis(series_name="BI", y_axis=bi_val, is_selected=True, symbol="diamond", symbol_size=10, label_opts=label_not_show_opts, itemstyle_opts=opts.ItemStyleOpts( color="rgba(184, 117, 225, 1.0)", )) chart_bi.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) chart_k = chart_k.overlap(chart_bi) if xd: xd_dts = [x['dt'] for x in xd] xd_val = [x['xd'] for x in xd] chart_xd = Scatter() chart_xd.add_xaxis(xd_dts) chart_xd.add_yaxis(series_name="XD", y_axis=xd_val, is_selected=True, symbol="triangle", symbol_size=10, itemstyle_opts=opts.ItemStyleOpts( color="rgba(37, 141, 54, 1.0)", )) chart_xd.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) chart_k = chart_k.overlap(chart_xd) if bs: b_dts = [x['dt'] for x in bs if x['mark'] == 'buy'] if len(b_dts) > 0: b_val = [x['buy'] for x in bs if x['mark'] == 'buy'] chart_b = Scatter() chart_b.add_xaxis(b_dts) chart_b.add_yaxis(series_name="BUY", y_axis=b_val, is_selected=False, symbol="arrow", symbol_size=8, itemstyle_opts=opts.ItemStyleOpts( color="#f31e1e", )) chart_b.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) chart_k = chart_k.overlap(chart_b) s_dts = [x['dt'] for x in bs if x['mark'] == 'sell'] if len(s_dts) > 0: s_val = [x['sell'] for x in bs if x['mark'] == 'sell'] chart_s = Scatter() chart_s.add_xaxis(s_dts) chart_s.add_yaxis(series_name="SELL", y_axis=s_val, is_selected=False, symbol="pin", symbol_size=12, itemstyle_opts=opts.ItemStyleOpts( color="#45b97d", )) chart_s.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) chart_k = chart_k.overlap(chart_s) # 成交量图 # ------------------------------------------------------------------------------------------------------------------ chart_vol = Bar() chart_vol.add_xaxis(dts) chart_vol.add_yaxis(series_name="Volume", y_axis=vol, bar_width='60%') chart_vol.set_global_opts( xaxis_opts=opts.AxisOpts( type_="category", grid_index=1, axislabel_opts=opts.LabelOpts(is_show=True, font_size=8, color="#9b9da9"), ), yaxis_opts=yaxis_opts, legend_opts=legend_not_show_opts, ) # MACD图 # ------------------------------------------------------------------------------------------------------------------ chart_macd = Bar() chart_macd.add_xaxis(dts) chart_macd.add_yaxis(series_name="MACD", y_axis=macd_bar, bar_width='60%') chart_macd.set_global_opts( xaxis_opts=opts.AxisOpts( type_="category", grid_index=2, axislabel_opts=opts.LabelOpts(is_show=False), ), yaxis_opts=opts.AxisOpts( grid_index=2, split_number=4, 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=True, color="#c7c7c7"), ), legend_opts=opts.LegendOpts(is_show=False), ) line = Line() line.add_xaxis(dts) line.add_yaxis(series_name="DIFF", y_axis=diff, label_opts=label_not_show_opts, is_symbol_show=False, linestyle_opts=opts.LineStyleOpts(opacity=0.8, width=1.0, color="#da6ee8")) line.add_yaxis(series_name="DEA", y_axis=dea, label_opts=label_not_show_opts, is_symbol_show=False, linestyle_opts=opts.LineStyleOpts(opacity=0.8, width=1.0, color="#39afe6")) chart_macd = chart_macd.overlap(line) grid0_opts = opts.GridOpts(pos_left="0%", pos_right="1%", pos_top="12%", height="58%") grid1_opts = opts.GridOpts(pos_left="0%", pos_right="1%", pos_top="74%", height="8%") grid2_opts = opts.GridOpts(pos_left="0%", pos_right="1%", pos_top="86%", height="10%") grid_chart = Grid(init_opts) grid_chart.add(chart_k, grid_opts=grid0_opts) grid_chart.add(chart_vol, grid_opts=grid1_opts) grid_chart.add(chart_macd, grid_opts=grid2_opts) return grid_chart
def ka_to_echarts(ka: KlineAnalyze, width="1500px", height='800px'): # 配置项设置 # ------------------------------------------------------------------------------------------------------------------ bg_color = "#1f212d" # 背景 up_color = "#F9293E" down_color = "#00aa3b" init_opts = opts.InitOpts(bg_color=bg_color, width=width, height=height, animation_opts=opts.AnimationOpts(False)) title_opts = opts.TitleOpts(title="{} - {}".format(ka.symbol, ka.name), subtitle="from {} to {}".format(ka.start_dt, ka.end_dt), pos_top="1%", title_textstyle_opts=opts.TextStyleOpts(color=up_color, font_size=20), subtitle_textstyle_opts=opts.TextStyleOpts(color=down_color, font_size=12)) label_not_show_opts = opts.LabelOpts(is_show=False) legend_not_show_opts = opts.LegendOpts(is_show=False) red_item_style = opts.ItemStyleOpts(color=up_color) green_item_style = opts.ItemStyleOpts(color=down_color) k_style_opts = opts.ItemStyleOpts(color=up_color, color0=down_color, border_color=up_color, border_color0=down_color, opacity=0.8) legend_opts = opts.LegendOpts(is_show=True, pos_top="1%", pos_left="30%", item_width=14, item_height=8, textstyle_opts=opts.TextStyleOpts(font_size=12, color="#0e99e2")) brush_opts = opts.BrushOpts(tool_box=["rect", "polygon", "keep", "clear"], x_axis_index="all", brush_link="all", out_of_brush={"colorAlpha": 0.1}, brush_type="lineX") axis_pointer_opts = opts.AxisPointerOpts(is_show=True, link=[{"xAxisIndex": "all"}]) dz_inside = opts.DataZoomOpts(False, "inside", xaxis_index=[0, 1, 2]) dz_slider = opts.DataZoomOpts(True, "slider", xaxis_index=[0, 1, 2], pos_top="96%", pos_bottom="0%") yaxis_opts = opts.AxisOpts(is_scale=True, axislabel_opts=opts.LabelOpts(color="#c7c7c7", font_size=8, position="inside")) grid0_xaxis_opts = opts.AxisOpts(type_="category", grid_index=0, axislabel_opts=label_not_show_opts, split_number=20, min_="dataMin", max_="dataMax", is_scale=True, boundary_gap=False, axisline_opts=opts.AxisLineOpts(is_on_zero=False)) tool_tip_opts = opts.TooltipOpts( trigger="axis", axis_pointer_type="cross", background_color="rgba(245, 245, 245, 0.8)", border_width=1, border_color="#ccc", position=JsCode(""" function (pos, params, el, elRect, size) { var obj = {top: 10}; obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 30; return obj; } """), textstyle_opts=opts.TextStyleOpts(color="#000"), ) # 数据预处理 # ------------------------------------------------------------------------------------------------------------------ dts = [x['dt'] for x in ka.kline_raw] k_data = [[x['open'], x['close'], x['low'], x['high']] for x in ka.kline_raw] ma = ka.ma vol = [] for row in ka.kline_raw: item_style = red_item_style if row['close'] > row['open'] else green_item_style bar = opts.BarItem(value=row['vol'], itemstyle_opts=item_style, label_opts=label_not_show_opts) vol.append(bar) macd = [] for row in ka.macd: item_style = red_item_style if row['macd'] > 0 else green_item_style bar = opts.BarItem(value=round(row['macd'], 4), itemstyle_opts=item_style, label_opts=label_not_show_opts) macd.append(bar) diff = [round(x['diff'], 4) for x in ka.macd] dea = [round(x['dea'], 4) for x in ka.macd] # K 线主图 # ------------------------------------------------------------------------------------------------------------------ chart_k = Kline() chart_k.add_xaxis(xaxis_data=dts) chart_k.add_yaxis(series_name="Kline", y_axis=k_data, itemstyle_opts=k_style_opts) chart_k.set_global_opts( legend_opts=legend_opts, datazoom_opts=[dz_inside, dz_slider], yaxis_opts=yaxis_opts, tooltip_opts=tool_tip_opts, axispointer_opts=axis_pointer_opts, brush_opts=brush_opts, title_opts=title_opts, xaxis_opts=grid0_xaxis_opts ) # 均线图 # ------------------------------------------------------------------------------------------------------------------ chart_ma = Line() chart_ma.add_xaxis(xaxis_data=dts) ma_keys = [x for x in ma[0].keys() if "ma" in x][:3] ma_colors = ["#39afe6", "#da6ee8", "#00940b"] for i, k in enumerate(ma_keys): y_data = [x[k] for x in ma] chart_ma.add_yaxis(series_name=k.upper(), y_axis=y_data, is_smooth=True, is_selected=False, symbol_size=0, label_opts=label_not_show_opts, linestyle_opts=opts.LineStyleOpts(opacity=0.8, width=1.0, color=ma_colors[i])) chart_ma.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) chart_k = chart_k.overlap(chart_ma) # 缠论结果 # ------------------------------------------------------------------------------------------------------------------ fx_dts = [x['dt'] for x in ka.fx_list] fx_val = [x['fx'] for x in ka.fx_list] chart_fx = Scatter() chart_fx.add_xaxis(fx_dts) chart_fx.add_yaxis(series_name="FX", y_axis=fx_val, is_selected=False, symbol="circle", symbol_size=6, label_opts=label_not_show_opts, itemstyle_opts=opts.ItemStyleOpts(color="rgba(152, 147, 193, 1.0)",)) chart_fx.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) chart_k = chart_k.overlap(chart_fx) bi_dts = [x['dt'] for x in ka.bi_list] bi_val = [x['bi'] for x in ka.bi_list] chart_bi = Scatter() chart_bi.add_xaxis(bi_dts) chart_bi.add_yaxis(series_name="BI", y_axis=bi_val, is_selected=True, symbol="diamond", symbol_size=10, label_opts=label_not_show_opts, itemstyle_opts=opts.ItemStyleOpts(color="rgba(184, 117, 225, 1.0)",)) chart_bi.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) chart_k = chart_k.overlap(chart_bi) xd_dts = [x['dt'] for x in ka.xd_list] xd_val = [x['xd'] for x in ka.xd_list] chart_xd = Scatter() chart_xd.add_xaxis(xd_dts) chart_xd.add_yaxis(series_name="XD", y_axis=xd_val, is_selected=True, symbol="triangle", symbol_size=10, itemstyle_opts=opts.ItemStyleOpts(color="rgba(37, 141, 54, 1.0)",)) chart_xd.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) chart_k = chart_k.overlap(chart_xd) # 成交量图 # ------------------------------------------------------------------------------------------------------------------ chart_vol = Bar() chart_vol.add_xaxis(dts) chart_vol.add_yaxis(series_name="Volume", y_axis=vol, bar_width='60%') chart_vol.set_global_opts( xaxis_opts=opts.AxisOpts( type_="category", grid_index=1, axislabel_opts=opts.LabelOpts(is_show=True, font_size=8, color="#9b9da9"), ), yaxis_opts=yaxis_opts, legend_opts=legend_not_show_opts, ) # MACD图 # ------------------------------------------------------------------------------------------------------------------ chart_macd = Bar() chart_macd.add_xaxis(dts) chart_macd.add_yaxis(series_name="MACD", y_axis=macd, bar_width='60%') chart_macd.set_global_opts( xaxis_opts=opts.AxisOpts( type_="category", grid_index=2, axislabel_opts=opts.LabelOpts(is_show=False), ), yaxis_opts=opts.AxisOpts( grid_index=2, split_number=4, 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=True, color="#c7c7c7"), ), legend_opts=opts.LegendOpts(is_show=False), ) line = Line() line.add_xaxis(dts) line.add_yaxis(series_name="DIFF", y_axis=diff, label_opts=label_not_show_opts, is_symbol_show=False, linestyle_opts=opts.LineStyleOpts(opacity=0.8, width=1.0, color="#da6ee8")) line.add_yaxis(series_name="DEA", y_axis=dea, label_opts=label_not_show_opts, is_symbol_show=False, linestyle_opts=opts.LineStyleOpts(opacity=0.8, width=1.0, color="#39afe6")) chart_macd = chart_macd.overlap(line) grid0_opts = opts.GridOpts(pos_left="0%", pos_right="1%", pos_top="12%", height="58%") grid1_opts = opts.GridOpts(pos_left="0%", pos_right="1%", pos_top="74%", height="8%") grid2_opts = opts.GridOpts(pos_left="0%", pos_right="1%", pos_top="86%", height="10%") grid_chart = Grid(init_opts) grid_chart.add(chart_k, grid_opts=grid0_opts) grid_chart.add(chart_vol, grid_opts=grid1_opts) grid_chart.add(chart_macd, grid_opts=grid2_opts) return grid_chart
def to_grid(ka, kline_mode: str = "new", with_bi: bool = False, with_xd: bool = False, with_zs: bool = False, with_bs: bool = False, with_ma: bool = False, with_vol: bool = False, with_macd: bool = False, title: str = "ChanLun In Practise", width: str = "1440px", height: str = '900px') -> Grid: """绘制缠中说禅K线分析结果 :param kline: K线 new / raw,new标识标准化后的k线,raw标识原始k线 :param with_bi: 是否显示笔识别结果,默认True,不输出False :param with_xd: 是否显示线段识别结果 :param with_zs: 是否显示中枢识别结果 :param with_bs: 是否显示买卖点 :param with_ma: 是否显示均线,默认True,不输出False :param with_macd: 是否显示macd,默认True,不输出False :param with_vol: 是否显示成交量,默认True,不输出False :param title: 图表标题 :param width: 图表宽度 :param height: 图表高度 :return: 用Grid组合好的图表 """ # 配置项设置 # ------------------------------------------------------------------------------------------------------------------ bg_color = "#1f212d" # 背景 up_color = "#F9293E" down_color = "#00aa3b" init_opts = opts.InitOpts(bg_color=bg_color, width='1400px', height='800px') title_opts = opts.TitleOpts(title=title, pos_top="1%", title_textstyle_opts=opts.TextStyleOpts(color=up_color, font_size=20), subtitle_textstyle_opts=opts.TextStyleOpts(color=down_color, font_size=12)) label_not_show_opts = opts.LabelOpts(is_show=False) legend_not_show_opts = opts.LegendOpts(is_show=False) red_item_style = opts.ItemStyleOpts(color=up_color) green_item_style = opts.ItemStyleOpts(color=down_color) k_style_opts = opts.ItemStyleOpts(color=up_color, color0=down_color, border_color=up_color, border_color0=down_color, opacity=0.8) legend_opts = opts.LegendOpts(is_show=True, pos_top="1%", pos_left="30%", item_width=14, item_height=8, textstyle_opts=opts.TextStyleOpts(font_size=12, color="#0e99e2")) brush_opts = opts.BrushOpts(tool_box=["rect", "polygon", "keep", "clear"], x_axis_index="all", brush_link="all", out_of_brush={"colorAlpha": 0.1}, brush_type="lineX") axis_pointer_opts = opts.AxisPointerOpts(is_show=True, link=[{"xAxisIndex": "all"}]) dz_inside = opts.DataZoomOpts(False, "inside", xaxis_index=[0, 1, 2]) dz_slider = opts.DataZoomOpts(True, "slider", xaxis_index=[0, 1, 2], pos_top="96%", pos_bottom="0%") yaxis_opts = opts.AxisOpts(is_scale=True, axislabel_opts=opts.LabelOpts(color="#c7c7c7", font_size=8, position="inside")) grid0_xaxis_opts = opts.AxisOpts(type_="category", grid_index=0, axislabel_opts=label_not_show_opts, split_number=20, min_="dataMin", max_="dataMax", is_scale=True, boundary_gap=False, axisline_opts=opts.AxisLineOpts(is_on_zero=False)) tool_tip_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"), ) # 数据预处理 # ------------------------------------------------------------------------------------------------------------------ kline = ka.kline_new if kline_mode == 'new' else ka.kline_raw dts = [x['dt'] for x in kline] k_data = [[x['open'], x['close'], x['low'], x['high']] for x in kline] # seriesname aggregation = len(ka.ka_list)>0 # {'freq': {'kline', 'ma', 'vol', 'macd'}} agg_dict = {} agg_dict[ka.freq] = { "kline": k_data, "ma": ka.ma, "vol": kline, "macd": ka.macd } if aggregation: for high_ka in ka.ka_list: agg_dict[high_ka.freq] = {} _high_k_data = high_ka.kline_new if kline_mode == 'new' else high_ka.kline_raw high_k_data = [] high_ma_data = [] high_vol_data = [] high_macd_data = [] for i in range(len(dts)): high_k_data.append([]) high_ma_data.append({}) high_vol_data.append(None) high_macd_data.append(None) for ki in range(len(kline)): k = kline[ki] _start = 0 for h_ki in range(_start, len(_high_k_data)): h_k = _high_k_data[h_ki] if (h_k['dt'] == k['dt']): high_k_data[ki] = [h_k['open'], h_k['close'], h_k['low'], h_k['high']] high_ma_data[ki] = high_ka.ma[h_ki] high_vol_data[ki] = h_k high_macd_data[ki] = high_ka.macd[h_ki] _start = h_ki+1 break agg_dict[high_ka.freq] = { "kline": high_k_data, "ma": high_ma_data, "vol": high_vol_data, "macd": high_macd_data } # K 线主图 # ------------------------------------------------------------------------------------------------------------------ chart_k = Kline() chart_k.add_xaxis(xaxis_data=dts) for k, v in agg_dict.items(): chart_k.add_yaxis(series_name=k if aggregation else 'kline', y_axis=v['kline'], itemstyle_opts=k_style_opts) is_selected = False chart_k.set_global_opts( legend_opts=legend_opts, datazoom_opts=[dz_inside, dz_slider], yaxis_opts=yaxis_opts, tooltip_opts=tool_tip_opts, axispointer_opts=axis_pointer_opts, brush_opts=brush_opts, title_opts=title_opts, xaxis_opts=grid0_xaxis_opts, ) if with_ma: # 均线图 # ------------------------------------------------------------------------------------------------------------------ ma_keys = [x for x in agg_dict[ka.freq]['ma'][0].keys() if "ma" in x][:3] ma_colors = ["#39afe6", "#da6ee8", "#00940b"] chart_ma = Line() chart_ma.add_xaxis(xaxis_data=dts) for key, vals in agg_dict.items(): for i, k in enumerate(ma_keys): y_data = [x[k] if k in x else None for x in v['ma']] chart_ma.add_yaxis(series_name=key if aggregation else k.upper(), y_axis=y_data, is_smooth=True, is_selected=True, is_connect_nones=True, symbol_size=0, label_opts=label_not_show_opts, linestyle_opts=opts.LineStyleOpts(opacity=0.8, width=1.0, color=ma_colors[i])) chart_ma.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) chart_k = chart_k.overlap(chart_ma) # 缠论结果 # ------------------------------------------------------------------------------------------------------------------ def __draw_bi_line(_ka): bi_dts = [x['dt'] for x in _ka.bi_list] bi_val = [x['bi'] for x in _ka.bi_list] chart_bi = Line() chart_bi.add_xaxis(bi_dts) chart_bi.add_yaxis(series_name=_ka.freq if aggregation else "BI", y_axis=bi_val, is_selected=True, symbol="diamond", symbol_size=10, label_opts=label_not_show_opts,) chart_bi.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) return chart_bi if with_bi: chark_k = chart_k.overlap(__draw_bi_line(ka)) for _ka in ka.ka_list: chark_k = chart_k.overlap(__draw_bi_line(_ka)) def __draw_xd_line(_ka): xd_dts = [x['dt'] for x in _ka.xd_list] xd_val = [x['xd'] for x in _ka.xd_list] chart_xd = Line() chart_xd.add_xaxis(xd_dts) chart_xd.add_yaxis(series_name=_ka.freq if aggregation else "XD", y_axis=xd_val, is_selected=True, symbol="triangle", symbol_size=10,) chart_xd.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) return chart_xd if with_xd: chark_k = chart_k.overlap(__draw_xd_line(ka)) for _ka in ka.ka_list: chark_k = chart_k.overlap(__draw_xd_line(_ka)) def __draw_zs_area(_ka): lines = [] scatters = [] for _zs in _ka.zs_list: x_start = _zs['start_point']['dt'] if _zs['zs_finished']:# 中枢完成 x_end = _zs['end_point']['dt'] chart_b = EffectScatter() if 'buy3' in _zs: chart_b.add_xaxis([_zs['buy3']['dt']]) chart_b.add_yaxis(series_name=_ka.freq if aggregation else "B", y_axis=[_zs['buy3']['xd']], is_selected=False, symbol="circle", symbol_size=8, itemstyle_opts=opts.ItemStyleOpts(color="red",)) chart_b.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) scatters.append(chart_b) elif 'sell3' in _zs: chart_b.add_xaxis([_zs['sell3']['dt']]) chart_b.add_yaxis(series_name=_ka.freq if aggregation else "S", y_axis=[_zs['sell3']['xd']], is_selected=False, symbol="circle", symbol_size=8, itemstyle_opts=opts.ItemStyleOpts(color="green",)) chart_b.set_global_opts(xaxis_opts=grid0_xaxis_opts, legend_opts=legend_not_show_opts) scatters.append(chart_b) elif len(_zs['points'])>=5:# 中枢成立但未完成,有3笔或段以上 x_end = _zs['points'][-1]['dt'] else: # 中枢未完成,且未确定 continue ZD = _zs['ZD'] ZG = _zs['ZG'] area_data=[[ {'xAxis': x_start, 'yAxis': ZD, 'value': ZD }, {'xAxis': x_end, 'yAxis': ZG, 'value': ZG }]] line = (Line() .add_xaxis([x_start, x_end]) .add_yaxis(series_name=_ka.freq if aggregation else "ZS", y_axis=[ZD, ZG], symbol='none' """ , markpoint_opts = opts.MarkPointOpts( data=[ opts.MarkPointItem(type_="max", name="ZG"), opts.MarkPointItem(type_="min", name="ZD"), ] ) """ , markline_opts=opts.MarkLineOpts( label_opts=opts.LabelOpts( position="middle", color="blue", font_size=15, ), linestyle_opts=opts.LineStyleOpts(type_="dashed"), data=area_data, symbol=["none", "none"], ) ) .set_series_opts( markarea_opts=opts.MarkAreaOpts(data=area_data, itemstyle_opts=opts.ItemStyleOpts(color="#dcdcdc",opacity=0.1)) )) lines.append(line) return lines, scatters if with_zs: _areas, _scatters = __draw_zs_area(ka) for _ka in ka.ka_list: _a, _s = __draw_zs_area(_ka) _areas.extend(_a) _scatters.extend(_s) for _area in _areas: chark_k = chart_k.overlap(_area) for _scatter in _scatters: chark_k = chart_k.overlap(_scatter) # if with_vol: # 成交量图 # ------------------------------------------------------------------------------------------------------------------ chart_vol = Bar() chart_vol.add_xaxis(dts) for k, v in agg_dict.items(): vol = [] for row in v['vol']: if not row: row = {'close': 0, 'open': 0, 'vol': 0} item_style = red_item_style if row['close'] > row['open'] else green_item_style bar = opts.BarItem(name=None, value=row['vol'], itemstyle_opts=item_style, label_opts=label_not_show_opts) vol.append(bar) chart_vol.add_yaxis(series_name=k if aggregation else "Volume", y_axis=vol, bar_width='60%') chart_vol.set_global_opts( xaxis_opts=opts.AxisOpts( type_="category", grid_index=1, axislabel_opts=opts.LabelOpts(is_show=True, font_size=8, color="#9b9da9"), ), yaxis_opts=yaxis_opts, legend_opts=legend_not_show_opts, ) #if with_macd: # MACD图 # ------------------------------------------------------------------------------------------------------------------ chart_macd = Bar() chart_macd.add_xaxis(dts) for k, v in agg_dict.items(): macd_bar = [] for row in v['macd']: if not row: row = {'macd': 0} item_style = red_item_style if row['macd'] > 0 else green_item_style bar = opts.BarItem(name=None, value=round(row['macd'], 4), itemstyle_opts=item_style, label_opts=label_not_show_opts) macd_bar.append(bar) chart_macd.add_yaxis(series_name=k if aggregation else "MACD", y_axis=macd_bar, bar_width='60%') chart_macd.set_global_opts( xaxis_opts=opts.AxisOpts( type_="category", grid_index=2, axislabel_opts=opts.LabelOpts(is_show=False), ), yaxis_opts=opts.AxisOpts( grid_index=2, split_number=4, 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=True, color="#c7c7c7"), ), legend_opts=opts.LegendOpts(is_show=False), ) line = Line() line.add_xaxis(dts) for k, v in agg_dict.items(): macd = v['macd'] diff = [round(x['diff'], 4) if x else None for x in macd] dea = [round(x['dea'], 4) if x else None for x in macd] line.add_yaxis(series_name=k if aggregation else "DIFF", y_axis=diff, label_opts=label_not_show_opts, is_symbol_show=False , is_connect_nones=True, linestyle_opts=opts.LineStyleOpts(opacity=0.8, width=1.0, color="#EDCB89")) line.add_yaxis(series_name=k if aggregation else "DEA", y_axis=dea, label_opts=label_not_show_opts, is_symbol_show=False , is_connect_nones=True, linestyle_opts=opts.LineStyleOpts(opacity=0.8, width=1.0, color="#FFFFFF")) chart_macd = chart_macd.overlap(line) grid0_opts = opts.GridOpts(pos_left="3%", pos_right="1%", pos_top="12%", height="58%") grid1_opts = opts.GridOpts(pos_left="3%", pos_right="1%", pos_top="74%", height="8%") grid2_opts = opts.GridOpts(pos_left="3%", pos_right="1%", pos_top="86%", height="10%") grid_chart = Grid(init_opts) grid_chart.add(chart_k, grid_opts=grid0_opts) grid_chart.add(chart_vol, grid_opts=grid1_opts) grid_chart.add(chart_macd, grid_opts=grid2_opts) return grid_chart
linestyle_opts=opts.LineStyleOpts(width=1.2, color='#4b0101')) # 添加其他折线图 line2 = Line() line2.add_xaxis(time_data) line2.add_yaxis( series_name='疑似数', y_axis=suspect_num, color='#fed0fc', # 标签配置 label_opts=opts.LabelOpts(is_show=False), # 线 linestyle_opts=opts.LineStyleOpts(width=1.2, color='#fed0fc')) # 合并两个图 sumx = bar.overlap(line1).overlap(line2) # 组合 all_ = Grid(init_opts=opts.InitOpts( width='1750px', # 宽度 height='654px', # 高度 theme=ThemeType.PURPLE_PASSION, )) all_.add( sumx, grid_opts=opts.GridOpts(pos_left='5%', pos_top='20%', pos_right='40%'), is_control_axis_index=True, ) # 生成
def create_mixed_line_and_bar(type, title, x_list, data_list, data_unit1, data_unit2 = None): """ :param type: 1-折线用于表示变化率and单柱状图+单折线 2-折线用于表示变化率and多柱状图+多折线 3-折线表示占比and单柱状图+单折线 4-折线表示占比and多柱状图+多折线 5-折线用于描述另一维度指标(此时data_list中最后一个k-v为折线数据) :param title: 图表名称 :param x_list: 横坐标内容为时间序列,纵坐标高度为多个(同级)指标的总和,具体各个指标的数值、比例以不同颜色标出 :param data_list: 字典{key1:value1,key2:value2...},构成柱状图的多个不同类型的bar :param data_unit1: 第一根y轴的数值单位 :param data_unit2: 第二根y轴的数值单位 :return: """ c = Bar(init_opts=opts.InitOpts(height="600px",width="900px",theme=ThemeType.MACARONS)) c.add_xaxis(x_list) if type == 1: # 因为有overlap,所以需要自适应调整刻度范围,是的bar和line都能显示出来 all_rate_list = [] for key in data_list.keys(): # 单柱状图只有一个bar change_rate_list = [0] c.add_yaxis(key, data_list[key], bar_width="20%",label_opts=opts.LabelOpts(is_show=True)) for i in range(1,len(data_list[key])): if data_list[key][i-1] == 0 or data_list[key][i-1] is None or data_list[key][i] is None: # 注意分母不为0 change_rate_list.append(None) else: change_rate_list.append(round((data_list[key][i]-data_list[key][i-1])/data_list[key][i-1]*100,2)) all_rate_list.append(change_rate_list) c.extend_axis(yaxis=opts.AxisOpts( name="变化率", type_="value", min_=int(round((getMinRate(all_rate_list)-(getMaxRate(all_rate_list)-getMinRate(all_rate_list)))/10)*10), max_=int(round((getMaxRate(all_rate_list)/10)*10)), interval=10, axislabel_opts=opts.LabelOpts(formatter="{value} %"), )) line = ( Line() .add_xaxis(xaxis_data=x_list) .add_yaxis( series_name="增长率", yaxis_index=1, y_axis=all_rate_list[0], label_opts=opts.LabelOpts(is_show=True, formatter=JsCode( "function(x){console.log(x);return Number(x.data[1]).toFixed(2) + '%';}" )), ) ) c.set_global_opts(title_opts=opts.TitleOpts(title=title,# subtitle="数据来源国家统计局", # pos_left="center",pos_bottom="0px", # item_gap=2, # subtitle_textstyle_opts=opts.TextStyleOpts(color="black") ), legend_opts=opts.LegendOpts(pos_left="right"), yaxis_opts=opts.AxisOpts(name="单位:" + data_unit1, # name_location="end", # name_gap=5, # # name_rotate=45, min_=0, # 基本上指标数据都是为正的 max_=int(round(getMaxData(data_list)/10)*10)*2, interval=10, )) c.overlap(line) elif type == 2: count = len(data_list.keys()) all_rate_list = [] keys_list = [] for key in data_list.keys(): keys_list.append(key) change_rate_list = [0] c.add_yaxis(key, data_list[key], label_opts=opts.LabelOpts(is_show=True)) for i in range(1,len(data_list[key])): if data_list[key][i-1] == 0 or data_list[key][i-1] is None or data_list[key][i] is None: # 注意分母不为0 change_rate_list.append(None) else: change_rate_list.append(round((data_list[key][i]-data_list[key][i-1])/data_list[key][i-1]*100,2)) all_rate_list.append(change_rate_list) c.extend_axis(yaxis=opts.AxisOpts( name="变化率", type_="value", min_=int( round((getMinRate(all_rate_list) - (getMaxRate(all_rate_list) - getMinRate(all_rate_list))) / 10) * 10), max_=int(round((getMaxRate(all_rate_list) / 10) * 10)), interval=10, axislabel_opts=opts.LabelOpts(formatter="{value} %"), )) all_line = [] for i in range(count): line = ( Line() .add_xaxis(xaxis_data=x_list) .add_yaxis( series_name=keys_list[i] + "增长率", yaxis_index=1, y_axis=all_rate_list[i], label_opts=opts.LabelOpts(is_show=True, formatter=JsCode( "function(x){console.log(x);return Number(x.data[1]).toFixed(2) + '%';}" )), ) ) all_line.append(line) c.set_global_opts(title_opts=opts.TitleOpts(title=title, # subtitle="数据来源国家统计局", pos_left="center",pos_bottom="0px", # item_gap=2, # subtitle_textstyle_opts=opts.TextStyleOpts(color="black") ), legend_opts=opts.LegendOpts(pos_left="right"), yaxis_opts=opts.AxisOpts(name="单位:" + data_unit1, # name_location="end", # name_gap=5, # # name_rotate=45, min_=0, max_=int(round(getMaxData(data_list)/10)*10)*2, interval=10, )) for line in all_line: c.overlap(line) src_path = "./指标-年度-图片生成/" html_file_name = src_path + title + ".html" img_file_name = src_path + title + ".png" make_snapshot(snapshot, c.render(html_file_name), img_file_name) print(img_file_name+":生成完毕...")