如何用c++的mfc绘制柱状图
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用c++的mfc绘制柱状图相关的知识,希望对你有一定的参考价值。
用c++的mfc绘制柱状图的方法如下:
1:取GroupBox的区域,并保存四个值 左,上,右,下
//获取屏幕坐标
((CWnd*)GetDlgItem(IDC_STATIC_CHART))->GetWindowRect(rect);
//计算x轴y轴基本单位
int dx = (rect.right-rect.left)/50;
int dy = (rect.bottom-rect.top)/80;
//转换成对话框坐标
ScreenToClient(rect);
//保存4个值
int L = rect.left,R = rect.right,T = rect.top,B = rect.bottom;
GroupBox的区域我忘记标出来了,就在上面图中柱状图那一块
2:获取DC,这一步没什么好说的
CPaintDC dc(this);
3:画X轴,Y轴
//X
dc.MoveTo(L+dx*2,B-dy*3);
dc.LineTo(L+dx*49,B-dy*3);
//最后的那个箭头
dc.MoveTo(L+dx*49,B-dy*3);
dc.LineTo(L+dx*48,B-dy*2);
dc.MoveTo(L+dx*49,B-dy*3);
dc.LineTo(L+dx*48,B-dy*4);
Y轴同理,但是考虑到dx,dy的值不一样,当画Y轴的箭头时,需要交换dx和dy的位置
//纵坐标线 dc.MoveTo(L+dx*2,B-dy*3);
dc.LineTo(L+dx*2,B-dy*77);
dc.MoveTo(L+dx*2,B-dy*77);
//交换了dx,dy的位置
dc.LineTo(L+dx*2-dy,B-dy*77+dx);
dc.MoveTo(L+dx*2,B-dy*77);
//交换了dx,dy的位置
dc.LineTo(L+dx*2+dy,B-dy*77+dx);
绘制完结果如图:
4:画柱状图,这里主要根据前面计算dx,dy时,划分的数量来计算每个柱的宽度,以及柱间的间隔
//第一个柱状体的左下坐标
int x = L+dx*3;
int y = B-dy*3;
for(int i=0;i
CRect rc;
rc.left=x+i*dx*9;
rc.right=rc.left+dx*7;
rc.bottom=y;
rc.top=rc.bottom-dy*answer[index][i+1];
//这里把柱状图的信息输出,这里输出的是一个数字,因为要转换成字符串,比较麻烦
//处理了一下,肯定有简洁的处理方式,但是我也懒得去想了,我很懒的
dc.SetBkMode(TRANSPARENT);//设置透明背景,要不然输出文字之后会有一块白,难看
char num[10];
sprintf(num,"%d",answer[index][i+1]);
CString strnum(num);
dc.TextOutW((rc.left+rc.right)/2-dx,rc.bottom-dy*(answer[index][i+1]+3),strnum);
//画刷是我之前就定义好的,直接拿来用
dc.FillRect(&rc,brushs+i);
5:添加控件消息响应函数
维护一个全局变量index来保存当前题号,创建重绘函数updateInfo
void CEnglishReportDlg::updateInfo()
int count = choose_c[index];
int i;
//选项存在,赋值,L是宏命令与TEXT()相同功能
for(i=0;i
m_strLable[i] = choose[index][i];
//无此选项,置空
for(;i<5;i++)
m_strLable[i] = L"";
m_strTopic = topics[index];
//获取GroupBox区域,并转换成对话框坐标
CRect rect;
((CWnd*)GetDlgItem(IDC_STATIC_CHART))->GetWindowRect(rect);
ScreenToClient(rect);
//重绘此区域
InvalidateRect(rect);
//将控件变量更新到前台
UpdateData(FALSE);
函数1:响应ListBox的SelChange事件
void CEnglishReportDlg::OnLbnSelchangeListTopic()
// TODO: 在此添加控件通知处理程序代码
index = m_listtopic.GetCurSel();
updateInfo();
函数2:上一页按钮的Click事件
void CEnglishReportDlg::OnBnClickedButtonPre()
// TODO: 在此添加控件通知处理程序代码
if(index>0)
index--;
updateInfo();
m_listtopic.SetCurSel(index);
函数3:下一页按钮的Clicl事件
void CEnglishReportDlg::OnBnClickedButtonNext()
// TODO: 在此添加控件通知处理程序代码
if(index<19)
index++;
updateInfo();
m_listtopic.SetCurSel(index);
至此基本的功能都已经实现了,还差最后一步:
6:初始化对话框
for(int i=0;i<20;i++)
m_listtopic.AddString(topics[i]);
//index初始化为0,直接刷新
updateInfo();
m_listtopic.SetCurSel(index);
运行结果如下:
参考技术A 在对话框界面上画出统计后的柱状图。 提示:在OnPaint()函数中加入画线代码: CDC* pDC = GetDC(); //利用MFC的CDC类实现画线 CPoint pt1,pt2; //定义起点、终点 pt1.x = 100; pt1.y = 100; pt2.x = 200; pt2.y = 200; pDC->MoveTo(pt1); //线的起点 pDC->LineTo(pt2); //线的终点 ReleaseDC(pDC); //释放CDC 满意答案 网友回答 来自太平洋电脑网 - 第一专业IT门户网站2013-07-29读文件: int nData[20]; FILE *fpTxt; if( ( fpTxt = fopen ("C:\\1.txt","r")) == NULL ) MessageBox("打开文件失败","系统警告",MB_OK); return; for(int i=0;i>本回答被提问者采纳 参考技术B 可以用MSChart。python绘制图
如何用python绘制图表
摘要: 使用python绘制简单的图表,包括折线图、柱状图、条形图、饼图、散点图、气泡图、箱线图、直方图等。
前言
本文介绍如果使用python汇总常用的图表,与Excel的点选操作相比,用python绘制图表显得比较比较繁琐,尤其提现在对原始数据的处理上。但两者在绘制图表过程中的思路大致相同,Excel中能完成的工作python大多也能做到。为了能够更好使用python绘制图表,我们需要导入几个 Python 的基本软件包NumPy,Pandas,matplotlib。
NumPy 是用于科学计算与 Python 的基本软件包。它包含除其他外:
一个强大的 N 维数组对象
复杂的 (广播) 功能
为集成 C/c + + 和 Fortran 代码工具
有用的线性代数、 傅里叶变换和随机编号功能
除了其明显的科学用途,NumPy 也可以用作泛型数据高效多维容器。可以定义任意数据类型。这允许 NumPy 迅速、 无缝集成与各种各样的数据库。
Pandas 是连接 SciPy 和 NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。Comma-separated values (CSV) 文件表示在有关各方之间分发数据的最常见的方法之一。Pandas 提供了一种优化库功能来读写多种文件格式,包括 CSV 和高效的 HDF5 格式。
Matplotlib是一个Python的图形框架,类似于MATLAB和R语言。
在使用NumPy进行学习统计计算时是枯燥的,大量的数据令我们很头疼,所以我们需要把它图形化显示。
接下来我们进行实战
1,数据如下
issue_d | member_id | loan_amnt | term | grade | emp_length | annual_inc | loan_status | total_pymnt_inv | total_rec_int |
2016/6/16 | 1296599 | 5000 | 36 months | B | 10+ years | 24000 | Fully Paid | 5833.84 | 863.16 |
2016/9/13 | 1314167 | 2500 | 60 months | C | < 1 year | 30000 | Charged Off | 1008.71 | 435.17 |
2016/6/16 | 1313524 | 2400 | 36 months | C | 10+ years | 12252 | Fully Paid | 3005.67 | 605.67 |
2016/4/16 | 1277178 | 10000 | 36 months | C | 10+ years | 49200 | Fully Paid | 12231.89 | 2214.92 |
2016/6/16 | 1311748 | 3000 | 60 months | B | 1 year | 80000 | Current | 3581.12 | 1042.85 |
2016/1/16 | 1311441 | 5000 | 36 months | A | 3 years | 36000 | Fully Paid | 5632.21 | 632.21 |
2016/5/16 | 1304742 | 7000 | 60 months | C | 8 years | 47004 | Fully Paid | 10137.84 | 3137.84 |
######## | 1288686 | 3000 | 36 months | E | 9 years | 48000 | Fully Paid | 3939.14 | 939.14 |
2016/8/12 | 1306957 | 5600 | 60 months | F | 4 years | 40000 | Charged Off | 646.02 | 294.94 |
2016/3/13 | 1306721 | 5375 | 60 months | B | < 1 year | 15000 | Charged Off | 1469.34 | 533.42 |
######## | 1305201 | 6500 | 60 months | C | 5 years | 72000 | Fully Paid | 7678.02 | 1178.02 |
2016/8/13 | 1305008 | 12000 | 36 months | B | 10+ years | 75000 | Fully Paid | 13947.99 | 1947.99 |
######## | 1298717 | 9000 | 36 months | C | < 1 year | 30000 | Charged Off | 2270.7 | 570.26 |
2016/6/16 | 1304956 | 3000 | 36 months | B | 3 years | 15000 | Fully Paid | 3480.27 | 480.27 |
2016/6/17 | 140597 | 4000 | 12 months | D | 1 year | 10000 | Charged Off | 1200.02 | 500 |
1,圆形图
# coding=utf-8 __author__ = ‘Jay‘ import pandas as pd # 导入图表库以进行图表绘制 import matplotlib.pyplot as plt plt.rcParams[‘font.sans-serif‘] = [‘SimHei‘] plt.rcParams[‘font.serif‘] = [‘SimHei‘] plt.rcParams[‘axes.unicode_minus‘] = False # 用控制中文乱码 loandata = pd.DataFrame(pd.read_excel(‘loan_data.xlsx‘)) # 按用户等级grade字段对贷款金额进行求和汇总 loan_grade = loandata.groupby(‘grade‘)[‘loan_amnt‘].agg(sum) # 设置饼图中每个数据分类的颜色 colors = ["#99CC01", "#FFFF01", "#0000FE", "#FE0000", "#A6A6A6", "#D9E021"] # 设置饼图中每个数据分类的名称 name = [u‘A级‘, u‘B级‘, u‘C级‘, u‘D级‘, u‘E级‘, u‘F级‘] # 创建饼图,设置分类标签,颜色和图表起始位置等, # labels (每一块)饼图外侧显示的说明文字 # loan_grade (每一块)的比例,如果sum(x) > 1会使用sum(x)归一化 # explode (每一块)离开中心距离 plt.pie(loan_grade, labels=name, colors=colors, explode=(0, 0, 0.1, 0, 0.1, 0), startangle=60, autopct=‘%1.1f%%‘) # 添加图表标题 plt.title(u‘不同用户等级的贷款金额占比‘) # 添加图例,并设置显示位置 plt.legend(name, loc=‘upper left‘) # 显示图表 plt.show()
2,条形图
# coding=utf-8 # LOCALTION = [3, 4, 5, 6, 7, 8] __author__ = ‘Jay‘ import numpy as np import pandas as pd # 导入图表库以进行图表绘制 import matplotlib.pyplot as plt plt.rcParams[‘font.sans-serif‘] = [‘SimHei‘] plt.rcParams[‘font.serif‘] = [‘SimHei‘] plt.rcParams[‘axes.unicode_minus‘] = False # 用控制中文乱码 loandata = pd.DataFrame(pd.read_excel(‘loan_data.xlsx‘)) # 按用户等级grade字段对贷款金额进行求和汇总 loan_grade = loandata.groupby(‘grade‘)[‘loan_amnt‘].agg(sum) # 定义数据分类名称 LOCALTIONS = [u‘A级‘, u‘B级‘, u‘C级‘, u‘D级‘, u‘E级‘, u‘F级‘] # 创建一个一维数组赋值给LOCALTION LOCALTION = np.arange(len(LOCALTIONS)) # 设置饼图中每个数据分类的颜色 colors = ["#99CC01", "#FFFF01", "#0000FE", "#FE0000", "#A6A6A6", "#D9E021"] # a=np.array(LOCALTION) # 创建柱状图,数据源为按用户等级汇总的贷款金额,设置颜色,透明度和外边框颜色 plt.barh(LOCALTION, loan_grade, color=colors, alpha=0.8, align=‘center‘, edgecolor=‘white‘) # 设置x轴标签 plt.ylabel(u‘用户等级‘) # 设置y周标签 plt.xlabel(u‘贷款金额‘) # 设置图表标题 plt.title(u‘不同用户等级的贷款金额分布‘) # 设置图例的文字和在图表中的位置 plt.legend([u‘贷款金额‘], loc=‘upper right‘) # 设置背景网格线的颜色,样式,尺寸和透明度 plt.grid(color=‘#95a5a6‘, linestyle=‘--‘, linewidth=1, axis=‘y‘, alpha=0.4) # 设置数据分类名称 plt.yticks(LOCALTION + 0.4, LOCALTIONS) # 显示图表 plt.show()
3.线箱图
# coding=utf-8 __author__ = ‘Jay‘ import pandas as pd # 导入图表库以进行图表绘制 import matplotlib.pyplot as plt plt.rcParams[‘font.sans-serif‘] = [‘SimHei‘] plt.rcParams[‘font.serif‘] = [‘SimHei‘] plt.rcParams[‘axes.unicode_minus‘] = False # 用控制中文乱码 loandata = pd.DataFrame(pd.read_excel(‘loan_data.xlsx‘)) # 创建箱线图,数据源为贷款来源,设置横向显示 plt.boxplot(loandata[‘loan_amnt‘], 1, ‘rs‘, vert=False) # 添加x轴标题 plt.xlabel(u‘贷款金额‘) # 添加图表标题 plt.title(u‘贷款金额分布‘) # 设置背景网格线的颜色,样式,尺寸和透明度 plt.grid(color=‘#95a5a6‘, linestyle=‘--‘, linewidth=1, axis=‘both‘, alpha=0.4) # 显示图表 plt.show()
4.气泡图
# coding=utf-8 __author__ = ‘Jay‘ import pandas as pd # 导入图表库以进行图表绘制 import matplotlib.pyplot as plt plt.rcParams[‘font.sans-serif‘] = [‘SimHei‘] plt.rcParams[‘font.serif‘] = [‘SimHei‘] plt.rcParams[‘axes.unicode_minus‘] = False # 用控制中文乱码 loandata = pd.DataFrame(pd.read_excel(‘loan_data.xlsx‘)) # 按月汇总贷款金额及利息 loan_x = loandata[‘loan_amnt‘] loan_y = loandata[‘total_rec_int‘] loan_z = loandata[‘total_rec_int‘] # 设置气泡图颜色 colors = ["#99CC01", "#FFFF01", "#0000FE", "#FE0000", "#A6A6A6", "#D9E021", ‘#FFF16E‘, ‘#0D8ECF‘, ‘#FA4D3D‘, ‘#D2D2D2‘, ‘#FFDE45‘, ‘#9b59b6‘] # 创建气泡图贷款金额为x,利息金额为y,同时设置利息金额为气泡大小,并设置颜色透明度等。 plt.scatter(loan_x, loan_y, s=loan_z, color=colors, alpha=0.8) # 添加x轴标题 plt.xlabel(u‘贷款金额‘) # 添加y轴标题 plt.ylabel(u‘利息收入‘) # 添加图表标题 plt.title(u‘贷款金额与利息收入‘) # 设置背景网格线的颜色,样式,尺寸和透明度 plt.grid(color=‘#95a5a6‘, linestyle=‘--‘, linewidth=1, axis=‘both‘, alpha=0.4) # 显示图表 plt.show()
5.柱状图
# coding=utf-8 __author__ = ‘Jay‘ import numpy as np import pandas as pd #导入图表库以进行图表绘制 import matplotlib.pyplot as plt plt.rcParams[‘font.sans-serif‘] = [‘SimHei‘] plt.rcParams[‘font.serif‘] = [‘SimHei‘] plt.rcParams[‘axes.unicode_minus‘]=False #用控制中文乱码 loandata=pd.DataFrame(pd.read_excel(‘loan_data.xlsx‘)) #按用户等级grade字段对贷款金额进行求和汇总 loan_grade=loandata.groupby(‘grade‘)[‘loan_amnt‘].agg(sum) #创建一个一维数组赋值给a a=np.array([1,2,3,4,5,6]) #创建柱状图,数据源为按用户等级汇总的贷款金额,设置颜色,透明度和外边框颜色 plt.bar([1,2,3,4,5,6],loan_grade,color=‘#99CC01‘,alpha=0.8,align=‘center‘,edgecolor=‘white‘) #设置x轴标签 plt.xlabel(u‘用户等级‘) #设置y周标签 plt.ylabel(u‘贷款金额‘) #设置图表标题 plt.title(u‘不同用户等级的贷款金额分布‘) #设置图例的文字和在图表中的位置 plt.legend([u‘贷款金额‘], loc=‘upper right‘) #设置背景网格线的颜色,样式,尺寸和透明度 plt.grid(color=‘#95a5a6‘,linestyle=‘--‘, linewidth=1,axis=‘y‘,alpha=0.4) #设置数据分类名称 plt.xticks(a,(u‘A级‘,u‘B级‘,u‘C级‘,u‘D级‘,u‘E级‘,u‘F级‘)) #显示图表 plt.show()
6.散点图
# coding=utf-8 __author__ = ‘Jay‘ import pandas as pd #导入图表库以进行图表绘制 import matplotlib.pyplot as plt plt.rcParams[‘font.sans-serif‘] = [‘SimHei‘] plt.rcParams[‘font.serif‘] = [‘SimHei‘] plt.rcParams[‘axes.unicode_minus‘]=False #用控制中文乱码 loandata=pd.DataFrame(pd.read_excel(‘loan_data.xlsx‘)) #按月汇总贷款金额,以0填充空值 loan_x=loandata[‘loan_amnt‘] #按月汇总利息金额,以0填充空值 loan_y=loandata[‘total_rec_int‘] #创建散点图,贷款金额为x,利息金额为y,设置颜色,标记点样式和透明度等 plt.scatter(loan_x,loan_y,60,color=‘white‘,marker=‘*‘,edgecolors=‘#0D8ECF‘,linewidth=3,alpha=0.8) #添加x轴标题 plt.xlabel(u‘贷款金额‘) #添加y轴标题 plt.ylabel(u‘利息收入‘) #添加图表标题 plt.title(u‘贷款金额与利息收入‘) #设置背景网格线的颜色,样式,尺寸和透明度 plt.grid(color=‘#95a5a6‘,linestyle=‘--‘, linewidth=1,axis=‘both‘,alpha=0.4) #显示图表 plt.show()
7.折线图
# coding=utf-8 __author__ = ‘Jay‘ import numpy as np import pandas as pd #导入图表库以进行图表绘制 import matplotlib.pyplot as plt plt.rcParams[‘font.sans-serif‘] = [‘SimHei‘] plt.rcParams[‘font.serif‘] = [‘SimHei‘] plt.rcParams[‘axes.unicode_minus‘]=False #用来正常显示负号 loandata=pd.DataFrame(pd.read_excel(‘loan_data.xlsx‘)) loandata.set_index(‘issue_d‘) #按月对贷款金额loan_amnt求均值 loan_plot=loandata[‘loan_amnt‘] #创建一个一维数组赋值给a a=np.array([1,2,3,4,5,6,7,8,9,10,11,12]) #创建折线图,数据源为按月贷款均值,标记点,标记线样式,线条宽度,标记点颜色和透明度 plt.plot(loan_plot,‘g^‘,loan_plot,‘g-‘,color=‘#99CC01‘,linewidth=3,markeredgewidth=3,markeredgecolor=‘#99CC01‘,alpha=0.8) #添加x轴标签 plt.xlabel(u‘月份‘) #添加y周标签 plt.ylabel(u‘贷款金额‘) #添加图表标题 plt.title(u‘分月贷款金额分布‘) #添加图表网格线,设置网格线颜色,线形,宽度和透明度 plt.grid( color=‘#95a5a6‘,linestyle=‘--‘, linewidth=1 ,axis=‘y‘,alpha=0.4) #设置数据分类名称 plt.xticks(a, (u‘1月‘,u‘2月‘,u‘3月‘,u‘4月‘,u‘5月‘,u‘6月‘,u‘7月‘,u‘8月‘,u‘9月‘,u‘10月‘,u‘11月‘,u‘12月‘) ) #输出图表 plt.show()
自定义字体及配色
图表中所使用的字体,可以使用下面的字体名称替换family=后面的内容以改变图表中所显示的字体。
图表中的颜色,可以直接使用颜色名称,也可以使用简称来设置图表中使用的颜色,本文中没有使用默认的颜色,而是使用了自定义颜色。
自定义颜色的色号,本文中使用的是Hex色号,下面给出了Hex和RGB的对应关系,以及相应的颜色。可以使用下面的Hex色号替换本文中图表的颜色。
issue_d | member_id | loan_amnt | term | grade | emp_length | annual_inc | loan_status | total_pymnt_inv | total_rec_int |
2016/6/16 | 1296599 | 5000 | 36 months | B | 10+ years | 24000 | Fully Paid | 5833.84 | 863.16 |
2016/9/13 | 1314167 | 2500 | 60 months | C | < 1 year | 30000 | Charged Off | 1008.71 | 435.17 |
2016/6/16 | 1313524 | 2400 | 36 months | C | 10+ years | 12252 | Fully Paid | 3005.67 | 605.67 |
2016/4/16 | 1277178 | 10000 | 36 months | C | 10+ years | 49200 | Fully Paid | 12231.89 | 2214.92 |
2016/6/16 | 1311748 | 3000 | 60 months | B | 1 year | 80000 | Current | 3581.12 | 1042.85 |
2016/1/16 | 1311441 | 5000 | 36 months | A | 3 years | 36000 | Fully Paid | 5632.21 | 632.21 |
2016/5/16 | 1304742 | 7000 | 60 months | C | 8 years | 47004 | Fully Paid | 10137.84 | 3137.84 |
######## | 1288686 | 3000 | 36 months | E | 9 years | 48000 | Fully Paid | 3939.14 | 939.14 |
2016/8/12 | 1306957 | 5600 | 60 months | F | 4 years | 40000 | Charged Off | 646.02 | 294.94 |
2016/3/13 | 1306721 | 5375 | 60 months | B | < 1 year | 15000 | Charged Off | 1469.34 | 533.42 |
######## | 1305201 | 6500 | 60 months | C | 5 years | 72000 | Fully Paid | 7678.02 | 1178.02 |
2016/8/13 | 1305008 | 12000 | 36 months | B | 10+ years | 75000 | Fully Paid | 13947.99 | 1947.99 |
######## | 1298717 | 9000 | 36 months | C | < 1 year | 30000 | Charged Off | 2270.7 | 570.26 |
2016/6/16 | 1304956 | 3000 | 36 months | B | 3 years | 15000 | Fully Paid | 3480.27 | 480.27 |
2016/6/17 | 140597 | 4000 | 12 months | D | 1 year | 10000 | Charged Off | 1200.02 | 500 |
以上是关于如何用c++的mfc绘制柱状图的主要内容,如果未能解决你的问题,请参考以下文章