数据化运营案例chapter7_code--流量数据化运营案例


第七章  流量数据化运营

一、案例-基于自动节点树的数据异常原因下探分析

说明

  • 时间:2019-01-01
  • 作者:宋天龙(Tony Song)
  • 程序开发环境:win7 64位
  • Python版本:64位 3.7
  • 依赖库:datetime、numpy、pandas、graphviz
  • 程序输入:advertising_data.csv
  • 程序输出:打印输出并保存节点树图change_analysis_tree.png

程序

导入库

import datetime
import numpy as np
import pandas as pd
from graphviz import Digraph  # 画图用库

读取数据

raw_data = pd.read_csv('advertising_data.csv')

数据审查

# 数据概览
print('{:*^60}'.format('Data overview:'),'\n',raw_data.tail(2))#打印原始数据后2条
print('{:*^60}'.format('Data dtypes:'),'\n',raw_data.dtypes)# 数据类型
***********************Data overview:*********************** 
             date   source    site channel     media visit
10691  2018/6/14  手机_精准营销   UC浏览器      活动    网址导航热词     -
10692  2018/6/14     精准营销  360浏览器      活动  新安装页面欢迎页     -
************************Data dtypes:************************ 
 date       object
source     object
site       object
channel    object
media      object
visit      object
dtype: object
# 缺失值审查
na_cols = raw_data.isnull().any(axis=0)  # 查看每一列是否具有缺失值
print('{:*^60}'.format('NA Cols:'))
print(na_cols[na_cols]==True)  # 查看具有缺失值的列
print('Total NA lines is: {0}'.format(raw_data.isnull().any(axis=1).sum()))  # 查看具有缺失值的行总记录数
**************************NA Cols:**************************
Series([], dtype: bool)
Total NA lines is: 0

数据预处理

# 替换字符为0然后转换为整数型
raw_data['visit'] = raw_data['visit'].replace('-', 0).astype(np.int64)
print('{:*^60}'.format('Data overview:'))
print(raw_data.tail(2))
***********************Data overview:***********************
            date   source    site channel     media  visit
10691  2018/6/14  手机_精准营销   UC浏览器      活动    网址导航热词      0
10692  2018/6/14     精准营销  360浏览器      活动  新安装页面欢迎页      0
# 将字符串转换为日期格式
raw_data['date'] = pd.to_datetime(raw_data['date'], format='%Y/%m/%d')
print('{:*^60}'.format('Data dtypes:'))
print(raw_data.dtypes)
************************Data dtypes:************************
date       datetime64[ns]
source             object
site               object
channel            object
media              object
visit               int64
dtype: object

计算整体波动量

day_summary = raw_data.iloc[:, -1].groupby(raw_data.iloc[:, 0]).sum()  # 按天求和汇总
day_change_value = day_summary.diff(1).rename('change')  # 通过差分求平移1天后的变化量
day_change_rate = (day_change_value.shift(-1) / day_summary).round(3).rename('change_rate').shift(1)  # 求相对昨天的环比变化率
day_summary_total = pd.concat((day_summary, day_change_value, day_change_rate), axis=1)  # 整合为完整数据框
print('{:*^60}'.format('Data change summary:'))
print(day_summary_total.head())
********************Data change summary:********************
             visit   change  change_rate
date                                    
2018-05-15  117260      NaN          NaN
2018-05-16  166124  48864.0        0.417
2018-05-17  157727  -8397.0       -0.051
2018-05-18  155805  -1922.0       -0.012
2018-05-19  115644 -40161.0       -0.258

指定日期自动下探分解

# 定义变量
# 分解对象
dimension_list = ['source', 'site', 'channel', 'media']  # 指定要分析的维度:4个层级
# 日期对象
the_day = pd.datetime(2018, 6, 7)  # 指定要分析的日期
previous_day = the_day - datetime.timedelta(1)  # 自动获取前1天日期
# 日期列名
day_col1 = datetime.datetime.strftime(the_day,'%Y-%m-%d')
day_col2 = datetime.datetime.strftime(previous_day,'%Y-%m-%d')
# 数据对象
the_data = raw_data[raw_data['date'] == the_day].rename(columns={'visit': day_col1})  # 获得指定日期数据
previous_data = raw_data[raw_data['date'] == previous_day].rename(columns={'visit': day_col2})  # 获得前1天日期数据
C:\Users\12048\Anaconda3\lib\site-packages\ipykernel_launcher.py:5: FutureWarning: The pandas.datetime class is deprecated and will be removed from pandas in a future version. Import from datetime module instead.
  """
# 数据合并计算
# 合并两天的数据
data_merge = the_data.iloc[:,1:].merge(previous_data.iloc[:,1:],on=dimension_list,how='outer')
# 替换没有匹配的数据为0
data_merge = data_merge.fillna(0)
# 计算相对昨天的环比变化率
data_merge['change'] = data_merge[day_col1]-data_merge[day_col2] # 变化量
data_merge.head()
# 整体对象
visit,change,change_rate = day_summary_total[day_summary_total.index == the_day].values[0]
top_nodes = {'source':'all site','change':change,'change_rate':change_rate}
# 自动节点分解
main_nodes = [] # 主节点
other_nodes = [] # 其他节点
hidden_nodes = [] # 潜在节点
main_edges = [] # 主边
other_edges = [] # 其他边
dim_copy = ['source', 'site', 'channel', 'media', day_col2,'change']
for ind,dimension in enumerate(dimension_list):  # 遍历每个维度
    each_data = data_merge[dim_copy[ind:]] # 筛选数据
    each_merge = each_data.groupby([dimension],as_index=False)[day_col2,'change'].sum() # 计算变化量
    each_merge = each_merge.sort_values(['change']) # 排序
    each_merge['each_change_rate'] = each_merge['change']/each_merge[day_col2] # 环比变化率
    each_merge = each_merge.drop(day_col2,axis=1) # 丢弃当日visit数值列
    change_all = each_merge.sum().iloc[1] # 总变化量
    if change_all<0: # 下降
        # node
        main_values = each_merge.iloc[0].tolist() # 主因子节点
        main_nodes.append(main_values)
        other_nodes.append([f'{dimension}-others',change_all-main_values[1],1-main_values[2]])
        hidden_nodes.append(each_merge.iloc[-1].tolist())
        # 数据过滤
        data_merge = each_data[each_data[dimension]==each_merge.iloc[0].iloc[0]]
    else: # 上升
        # node
        main_values = each_merge.iloc[-1].tolist() # 其他因子节点
        main_nodes.append(main_values)
        other_nodes.append([f'{dimension}-others',change_all-main_values[1],1-main_values[2]])
        hidden_nodes.append(each_merge.iloc[0].tolist())
        # 数据过滤
        data_merge = each_data[each_data[dimension]==each_merge.iloc[-1].iloc[0]]  
    # edge
    edge_values = main_values[1]/float(change_all)
    main_edges.append(edge_values)
    other_edges.append(1-edge_values)
C:\Users\12048\Anaconda3\lib\site-packages\ipykernel_launcher.py:10: FutureWarning: Indexing with multiple keys (implicitly converted to a tuple of keys) will be deprecated, use a list instead.
  # Remove the CWD from sys.path while we load stuff.

画图展示自动下探结果

# 定义各个节点的样式
node_style = '<<table border="0"><tr><td width="20"><table border="1" cellspacing="0" VALIGN="MIDDLE"><tr><td bgcolor="{0}"><font color="{1}"><B>{2}</B></font></td></tr><tr><td>环比变化量:{3:d}</td></tr><tr><td>环比变化率:{4:.2%}</td></tr></table></td></tr></table>>'
edge_style = '<<table border="0"><tr><td><table border="0" cellspacing="0" VALIGN="MIDDLE" bgcolor="#ffffff"><tr><td>{0}</td></tr><tr><td>贡献率:{1:.0%}</td></tr></table></td></tr></table>>'
attr_node = {'fontname': "SimHei", 'shape': 'box','penwidth' : '0'}  # 定义node节点样式
attr_edge = {'fontname': "SimHei"}  # 定义edge节点样式
attr_graph = {'fontname': "SimHei", 'splines': 'ortho','nodesep' : '2'}  # Graph的总体样式
# 定义左侧父级图
parent_dot = Digraph(format='png', graph_attr=attr_graph, node_attr={'shape': 'plaintext', 'fontname': 'SimHei'}) 
features = ['全站','source', 'site', 'channel', 'media']
parent_edge = [(features[i],features[i+1]) for i in range(len(features)-1)]
parent_dot.edges(parent_edge)
# 定义右侧子级图
child_dot = Digraph(node_attr=attr_node, edge_attr=attr_edge)  # 创建有向图
for tree_depth in range(len(main_nodes)):  # 循环读取每一层
    split_node_left = main_nodes[tree_depth]
    split_node_right = other_nodes[tree_depth]
    split_node_hidden = hidden_nodes[tree_depth]

    if tree_depth == 0:
        # 增加顶部节点
        node_name = '汇总值'
        node_top_label = node_style.format( 'black',"white",node_name,
                                               int(top_nodes['change']),
                                               top_nodes['change_rate'])  # 分别获取顶部节点名称、变化量和变化率
        child_dot.node('汇总值', label=node_top_label)  # 增加顶部节点
    else:
        node_name = main_nodes[tree_depth - 1][0]  # 将上级左侧分裂节点作为下级节点的source

    # 增加node信息
    node_label_left = node_style.format("#184da5","white",split_node_left[0],
                                             int(split_node_left[1]),
                                             split_node_left[2])  # 左侧节点显示的信息
    node_label_right = node_style.format("#d3d3d3","black",split_node_right[0],
                                               int(split_node_right[1]),
                                               split_node_right[2])  # 右侧节点显示的信息
    node_label_hidden = node_style.format("#72a518","black",split_node_hidden[0],
                                               int(split_node_hidden[1]),
                                               split_node_hidden[2])  # 潜在节点显示的信息
    # 增加边信息
    edge_label_left = edge_style.format('主因子',main_edges[tree_depth])  # 左侧边的标签信息
    edge_label_right = edge_style.format('其他因子',other_edges[tree_depth])  # 右侧边的标签信息

    # 节点和边画图
    child_dot.node(split_node_left[0], label=node_label_left)  # 增加左侧节点
    child_dot.node(split_node_right[0], label=node_label_right)  # 增加右侧节点
    child_dot.node(split_node_hidden[0], label=node_label_hidden)  # 增加隐藏节点
    child_dot.edge(node_name, split_node_left[0], label=edge_label_left)  # 增加左侧边
    child_dot.edge(node_name, split_node_right[0], label=edge_label_right)  # 增加右侧边
    child_dot.edge(split_node_right[0], split_node_hidden[0],label = '潜在因子')  # 增加隐藏节点边

parent_dot.subgraph(child_dot)
parent_dot.view('change_analysis_tree')  # 展示图形结果
Warning: Orthogonal edges do not currently handle edge labels. Try using xlabels.






'change_analysis_tree.png'

二、案例-基于自动K值的KMeans广告效果聚类分析

说明

  • 时间:2019-01-01
  • 作者:宋天龙(Tony Song)
  • 程序开发环境:win7 64位
  • Python版本:64位 3.7
  • 依赖库:matplotlib、numpy、pandas、sklearn
  • 程序输入:ad_performance.txt
  • 程序输出:打印输出不同聚类类别的信息

程序

导入库

import matplotlib.pyplot as plt  # 图形库
import numpy as np
import pandas as pd
from sklearn.metrics import silhouette_score  # 导入轮廓系数指标
from sklearn.cluster import KMeans  # KMeans模块
from sklearn.preprocessing import MinMaxScaler, OneHotEncoder  # 数据预处理库

读取数据

raw_data = pd.read_table('ad_performance.txt', delimiter='\t')

数据审查

# 查看基本状态
print('{:*^60}'.format('Data overview:'))
print(raw_data.head(2))  # 打印输出前2条数据
print('{:*^60}'.format('Data dtypes:'))
print(pd.DataFrame(raw_data.dtypes).T)  # 打印数据类型分布
print('{:*^60}'.format('Data DESC:'))
print(raw_data.describe().round(2).T)  # 打印原始数据基本描述性信息
***********************Data overview:***********************
   渠道代号    日均UV   平均注册率   平均搜索量    访问深度  平均停留时间   订单转化率  投放总时间 素材类型    广告类型  \
0  A203    3.69  0.0071  0.0214  2.3071  419.77  0.0258     20  jpg  banner   
1  A387  178.70  0.0040  0.0324  2.0489  157.94  0.0030     19  jpg  banner   

  合作方式    广告尺寸 广告卖点  
0  roi  140*40   打折  
1  cpc  140*40   满减  
************************Data dtypes:************************
     渠道代号     日均UV    平均注册率    平均搜索量     访问深度   平均停留时间    订单转化率  投放总时间  \
0  object  float64  float64  float64  float64  float64  float64  int64   

     素材类型    广告类型    合作方式    广告尺寸    广告卖点  
0  object  object  object  object  object  
*************************Data DESC:*************************
        count    mean      std   min     25%     50%     75%       max
日均UV    889.0  540.85  1634.41  0.06    6.18  114.18  466.87  25294.77
平均注册率   889.0    0.00     0.00  0.00    0.00    0.00    0.00      0.04
平均搜索量   889.0    0.03     0.11  0.00    0.00    0.00    0.01      1.04
访问深度    889.0    2.17     3.80  1.00    1.39    1.79    2.22     98.98
平均停留时间  887.0  262.67   224.36  1.64  126.02  236.55  357.98   4450.83
订单转化率   889.0    0.00     0.01  0.00    0.00    0.00    0.00      0.22
投放总时间   889.0   16.05     8.51  1.00    9.00   16.00   24.00     30.00
# 缺失值审查
na_cols = raw_data.isnull().any(axis=0)  # 查看每一列是否具有缺失值
print('{:*^60}'.format('NA Cols:'))
print(na_cols[na_cols==True])  # 查看具有缺失值的列
print('Total number of NA lines is: {0}'.format(
    raw_data.isnull().any(axis=1).sum()))  # 查看具有缺失值的行总记录数
**************************NA Cols:**************************
平均停留时间    True
dtype: bool
Total number of NA lines is: 2
# 相关性分析
print('{:*^60}'.format('Correlation analysis:'))
print(raw_data.corr().round(2).T)  # 打印原始数据相关性信息
*******************Correlation analysis:********************
        日均UV  平均注册率  平均搜索量  访问深度  平均停留时间  订单转化率  投放总时间
日均UV    1.00  -0.05  -0.07 -0.02    0.04  -0.05  -0.04
平均注册率  -0.05   1.00   0.24  0.11    0.22   0.32  -0.01
平均搜索量  -0.07   0.24   1.00  0.06    0.17   0.13  -0.03
访问深度   -0.02   0.11   0.06  1.00    0.72   0.16   0.06
平均停留时间  0.04   0.22   0.17  0.72    1.00   0.25   0.05
订单转化率  -0.05   0.32   0.13  0.16    0.25   1.00  -0.00
投放总时间  -0.04  -0.01  -0.03  0.06    0.05  -0.00   1.00

数据预处理

# 删除平均平均停留时间列
raw_data2 = raw_data.drop(['平均停留时间'], axis=1)
# 字符串分类onehotencode处理
cols = ['素材类型','广告类型','合作方式','广告尺寸','广告卖点']
model_ohe = OneHotEncoder(sparse=False)  # 建立OneHotEncode对象
ohe_matrix = model_ohe.fit_transform(raw_data2[cols])  # 直接转换
print(ohe_matrix[:2])
[[0. 1. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 1. 1. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0.
  0. 0. 0.]
 [0. 1. 0. 0. 1. 0. 0. 0. 0. 1. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0.
  0. 0. 0.]]
# 数据标准化
sacle_matrix = raw_data2.iloc[:, 1:7]  # 获得要转换的矩阵
model_scaler = MinMaxScaler()  # 建立MinMaxScaler模型对象
data_scaled = model_scaler.fit_transform(sacle_matrix)  # MinMaxScaler标准化处理
print(data_scaled.round(2))
[[0.   0.18 0.02 0.01 0.12 0.66]
 [0.01 0.1  0.03 0.01 0.01 0.62]
 [0.   0.06 0.05 0.01 0.01 0.1 ]
 ...
 [0.01 0.01 0.   0.   0.   0.72]
 [0.05 0.   0.   0.   0.   0.31]
 [0.   0.   0.   0.53 0.   0.62]]
# 合并所有维度
X = np.hstack((data_scaled, ohe_matrix))

KMeans建模

# 通过平均轮廓系数检验得到最佳KMeans聚类模型
score_list = list()  # 用来存储每个K下模型的平局轮廓系数
silhouette_int = -1  # 初始化的平均轮廓系数阀值
for n_clusters in range(2, 5):  # 遍历从2到5几个有限组
    model_kmeans = KMeans(n_clusters=n_clusters)  # 建立聚类模型对象
    labels_tmp = model_kmeans.fit_predict(X)  # 训练聚类模型
    silhouette_tmp = silhouette_score(X, labels_tmp)  # 得到每个K下的平均轮廓系数
    if silhouette_tmp > silhouette_int:  # 如果平均轮廓系数更高
        best_k = n_clusters  # 保存K将最好的K存储下来
        silhouette_int = silhouette_tmp  # 保存平均轮廓得分
        best_kmeans = model_kmeans  # 保存模型实例对象
        cluster_labels_k = labels_tmp  # 保存聚类标签
    score_list.append([n_clusters, silhouette_tmp])  # 将每次K及其得分追加到列表
print('{:*^60}'.format('K value and silhouette summary:'))
print(np.array(score_list))  # 打印输出所有K下的详细得分
print('Best K is:{0} with average silhouette of {1}'.format(best_k, silhouette_int))
**************K value and silhouette summary:***************
[[2.         0.38655493]
 [3.         0.45864451]
 [4.         0.50209812]]
Best K is:4 with average silhouette of 0.5020981194788054

聚类结果分析

# part1 将原始数据与聚类标签整合
cluster_labels = pd.DataFrame(cluster_labels_k, columns=['clusters'])  # 获得训练集下的标签信息
merge_data = pd.concat((raw_data2, cluster_labels), axis=1)  # 将原始处理过的数据跟聚类标签整合

# part2 计算每个聚类类别下的样本量和样本占比
clustering_count = pd.DataFrame(merge_data['渠道代号'].groupby(merge_data['clusters']).count()).T.rename({'渠道代号': 'counts'})  # 计算每个聚类类别的样本量
clustering_ratio = (clustering_count / len(merge_data)).round(2).rename({'counts': 'percentage'})  # 计算每个聚类类别的样本量占比

# part3 计算各个聚类类别内部最显著特征值
cluster_features = []  # 空列表,用于存储最终合并后的所有特征信息
for line in range(best_k):  # 读取每个类索引
    label_data = merge_data[merge_data['clusters'] == line]  # 获得特定类的数据

    part1_data = label_data.iloc[:, 1:7]  # 获得数值型数据特征
    part1_desc = part1_data.describe().round(3)  # 得到数值型特征的描述性统计信息
    merge_data1 = part1_desc.iloc[2, :]  # 得到数值型特征的均值

    part2_data = label_data.iloc[:, 7:-1]  # 获得字符串型数据特征
    part2_desc = part2_data.describe(include='all')  # 获得字符串型数据特征的描述性统计信息
    merge_data2 = part2_desc.iloc[2, :]  # 获得字符串型数据特征的最频繁值

    merge_line = pd.concat((merge_data1, merge_data2), axis=0)  # 将数值型和字符串型典型特征沿行合并
    cluster_features.append(merge_line)  # 将每个类别下的数据特征追加到列表
# part4 输出完整的类别特征信息
cluster_pd = pd.DataFrame(cluster_features).T  # 将列表转化为矩阵
print('{:*^60}'.format('Detailed features for all clusters:'))
all_cluster_set = pd.concat((clustering_count, clustering_ratio, cluster_pd),axis=0)  # 将每个聚类类别的所有信息合并
print(all_cluster_set)
************Detailed features for all clusters:*************
                  0        1        2        3
counts          349      313      154       73
percentage     0.39     0.35     0.17     0.08
日均UV        933.015  1390.01  2717.42  1904.37
平均注册率         0.003    0.003    0.005    0.003
平均搜索量         0.064    0.152    0.051    0.106
访问深度          5.916    1.168    0.947    0.943
订单转化率         0.006    0.017    0.007    0.009
投放总时间          8.77    8.199    8.529    8.217
素材类型            jpg      swf      jpg      swf
广告类型             横幅      不确定   banner     tips
合作方式            cpc      roi      cpc      cpm
广告尺寸         600*90   600*90  308*388  450*300
广告卖点             直降       打折       满减       打折

各类别显著数值特征对比

# part1 各类别数据预处理
num_sets = cluster_pd.iloc[:6, :].T.astype(np.float64)  # 获取要展示的数据
num_sets_max_min = model_scaler.fit_transform(num_sets)  # 获得标准化后的数据
# part2 画布基本设置
fig = plt.figure(figsize=(6,6))  # 建立画布
ax = fig.add_subplot(111, polar=True)  # 增加子网格,注意polar参数
labels = np.array(merge_data1.index)  # 设置要展示的数据标签
cor_list = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'w']  # 定义不同类别的颜色
angles = np.linspace(0, 2 * np.pi, len(labels), endpoint=False)  # 计算各个区间的角度
angles = np.concatenate((angles, [angles[0]]))  # 建立相同首尾字段以便于闭合
# part3 画雷达图
for i in range(len(num_sets)):  # 循环每个类别
    data_tmp = num_sets_max_min[i, :]  # 获得对应类数据
    data = np.concatenate((data_tmp, [data_tmp[0]]))  # 建立相同首尾字段以便于闭合
    ax.plot(angles, data, 'o-', c=cor_list[i], label=i)  # 画线
# part4 设置图像显示格式
ax.set_thetagrids(angles * 180 / np.pi, labels, fontproperties="SimHei")  # 设置极坐标轴
ax.set_title("各聚类类别显著特征对比", fontproperties="SimHei")  # 设置标题放置
ax.set_rlim(-0.2, 1.2)  # 设置坐标轴尺度范围
plt.legend(loc=0)  # 设置图例位置
---------------------------------------------------------------------------

ValueError                                Traceback (most recent call last)

<ipython-input-25-c1527d6f5d8a> in <module>()
     15     ax.plot(angles, data, 'o-', c=cor_list[i], label=i)  # 画线
     16 # part4 设置图像显示格式
---> 17 ax.set_thetagrids(angles * 180 / np.pi, labels, fontproperties="SimHei")  # 设置极坐标轴
     18 ax.set_title("各聚类类别显著特征对比", fontproperties="SimHei")  # 设置标题放置
     19 ax.set_rlim(-0.2, 1.2)  # 设置坐标轴尺度范围


~\AppData\Roaming\Python\Python37\site-packages\matplotlib\projections\polar.py in set_thetagrids(self, angles, labels, fmt, **kwargs)
   1344         self.set_xticks(angles)
   1345         if labels is not None:
-> 1346             self.set_xticklabels(labels)
   1347         elif fmt is not None:
   1348             self.xaxis.set_major_formatter(mticker.FormatStrFormatter(fmt))


~\AppData\Roaming\Python\Python37\site-packages\matplotlib\axes\_base.py in wrapper(self, *args, **kwargs)
     61 
     62         def wrapper(self, *args, **kwargs):
---> 63             return get_method(self)(*args, **kwargs)
     64 
     65         wrapper.__module__ = owner.__module__


~\AppData\Roaming\Python\Python37\site-packages\matplotlib\cbook\deprecation.py in wrapper(*args, **kwargs)
    449                 "parameter will become keyword-only %(removal)s.",
    450                 name=name, obj_type=f"parameter of {func.__name__}()")
--> 451         return func(*args, **kwargs)
    452 
    453     return wrapper


~\AppData\Roaming\Python\Python37\site-packages\matplotlib\axis.py in _set_ticklabels(self, labels, fontdict, minor, **kwargs)
   1791         if fontdict is not None:
   1792             kwargs.update(fontdict)
-> 1793         return self.set_ticklabels(labels, minor=minor, **kwargs)
   1794 
   1795     @cbook._make_keyword_only("3.2", "minor")


~\AppData\Roaming\Python\Python37\site-packages\matplotlib\axis.py in set_ticklabels(self, ticklabels, minor, **kwargs)
   1713             if len(locator.locs) != len(ticklabels) and len(ticklabels) != 0:
   1714                 raise ValueError(
-> 1715                     "The number of FixedLocator locations"
   1716                     f" ({len(locator.locs)}), usually from a call to"
   1717                     " set_ticks, does not match"


ValueError: The number of FixedLocator locations (7), usually from a call to set_ticks, does not match the number of ticklabels (6).

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OjlDo11k-1608625885341)(output_48_1.png)]


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

灯下夜无眠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值