查看原文
其他

如何用Stata绘制带指向性箭头标注的图像

爬虫俱乐部 Stata and Python数据分析 2022-03-15

本文作者:邱   沣,河南大学经济学院

本文编辑:温和铭

技术总编:李婷婷

Stata&Python云端课程来啦!

       为了感谢大家长久以来的支持和信任,爬虫俱乐部为大家送福利啦!!!Stata&Python特惠课程双双上线腾讯课堂~爬虫俱乐部推出了Python编程培训课程Stata基础课程Stata进阶课程Stata文本分析正则表达式网络爬虫基本字符串课程。报名课程即可加入答疑群,对报名有任何疑问欢迎在公众号后台和腾讯课堂留言哦。我们在这篇推文的最后提供了每门课程的课程二维码,大家有需要的话可以直接扫描二维码查看课程详情并进行购买哦~




导读

众所周知,Stata拥有强大的画图功能,除了常见的条形图、折线图、饼图等等,我们也可以使用Stata画出一些有趣的小图形,今天要介绍的就是使用pcarrowi命令,绘制带指向性箭头标注的图像。



一、pcarrowi命令介绍
pcarrowi命令可以在绘图中加入指向性箭头并在后面跟上所要标注的文本,它脱胎于pcarrow命令(绘制带有箭头的成对坐标图),命令使用规范如下:
twoway pcarrowi immediate_values [,  options]

其中immediate_values指的是#y1 #x1 #y2 #x2 [(#_clockposstyle)] ["text for label"]

#y1 #x1 #y2 #x2 分别指的是箭头的起点和终点的坐标;

(#_clockposstyle)指的是箭头尾部所跟的标注内容的位置,一般为 1-12,而这些方位又恰好与时钟的12个点数位置相符,所以还是很方便使用的;

"text for label" 就很明显了,指的是我们要标注的内容,一般都用双引号引用起来。当然我们也可以将内容放在 text() 里当作 options 跟在其后。需要注意的是:使用text()命令时,需要在标注内容前加上坐标,比如:text(1.25 2.60 "标注内容")。



二、绘制单个箭头

接下来我们先举一些简单的例子,大家就知道该如何使用pcarrowi这个命令了。

比如我们画一个从坐标 (1 , 2) 到 (3 , 2) 的箭头并配上标注“爬虫俱乐部”,这里需要注意:命令中坐标点的输入是 (y , x) 而不是 (x , y)。

twoway pcarrowi 2 1 3 2 (6) "爬虫俱乐部" ,aspect(2) plotregion(margin(vlarge)) *转换标注位置twoway pcarrowi 2 1 3 2 (3) "爬虫俱乐部" ,aspect(2) plotregion(margin(vlarge))

如上述程序所述,标注“爬虫俱乐部”的位置分别在时钟的六点钟和三点钟方向,其中aspect(2) 为设置绘图区域纵横比为2,当然这里可更改为任意比例。plotregion选项可以设置绘图边缘大小。比如:

twoway pcarrowi 2 1 3 2 (6) "爬虫俱乐部" ,aspect(1) plotregion(margin(vlarge)) //设置纵横比为1twoway pcarrowi 2 1 3 2 (6) "爬虫俱乐部" ,aspect(2) plotregion(margin(small)) //设置内部区域边际为小



三、绘制多个箭头

下面我们来看如何在一个坐标系中绘制多个箭头:

twoway pcarrowi 0 0 0 1 (3) "3 o'clock" 0 0 1 0 (12) "12 o'clock", aspect(1) headlabel plotregion(margin(vlarge))

其中headlabel 指的是标注在箭头的头部,而不是尾部。

通过简单地添加同样格式的对箭头的设定就能实现绘制多个箭头及进行标注。那如果我们想绘制多个且长短不一的箭头该怎么实现呢?

twoway pcarrowi 2 2 2 4 (3) "3 o'clock" 2 2 4 2 (12) "12 o'clock" 2 2 2 0 (9) "9 o'clock", aspect(1) headlabel plotregion(margin(vlarge))

通过设置不同的起点、终点坐标就可以画出方向、长短不同的箭头,这里我们就绘制出来了简约版时钟中的八时十五秒(八点的看作时针,十二点的看作分针)。通过上边这些例子,我们可以看出如何画出箭头以及设置标注的位置。

紧接着我们看如何标注散点图中的特殊点,也就是如何在图形中添加多个指向性箭头标注。

sysuse auto,cleartwoway qfitci mpg weight,stdf || scatter mpg weight,ms(O) || pcarrowi 41 2200 41 2060 (3) "VW Diesel" 31 3460 28 3280 (3) "Plymouth Arrow"35 2250 35 2070 (3) "Datsun 210 and Subaru",legend(order(1 2 3))

首先我们绘制出散点图,并使用qfitci命令进行二次拟合并画出95%的置信区间,这时我们想标注那些特殊点就可以使用pcarrowi命令了,通过这些点的坐标我们可以确定箭头的终点,比如(41,2200),然后根据我们的所需就可以自定义箭头的起点,比如(41 2060),最后加上位置符(3)和所需标注内容就可以绘制出带标注的箭头了。

可以看出我们只要精准定义了坐标,就能很容易地绘制出所需长短的箭头了,接下来我们来看一下如何设置箭头的颜色,粗细,大小等。



四、如何设置箭头的样式

我们在日常的使用中,如何根据具体需求个性化地设置箭头标注呢?首先,可以借助 mstyle() 选项来设置总样式,可有p1-p15可选择。


01设置大小

msize(msiz) :箭头大小

barbsize(barb):箭头填充部分的大小

mlabsize :标注部分字体大小

其中选项从小到大有:

vtiny 、tiny、vsmall、small、medsmall、medium、medlarge、large、vlarge、huge、vhuge、ehuge

当然也能自定义大小,help size可获取具体方式。

接下来我们一步步演示如何设置箭头和标注的大小,先看如何设置单个箭头:

twoway pcarrowi 2 1 3 2 (3) "爬虫俱乐部" ,msize(vlarge) aspect(2) plotregion(margin(vlarge))

通过msize选项,我们改变了箭头的大小。
twoway pcarrowi 2 1 3 2 (3) "爬虫俱乐部" ,barbsize(vlarge) aspect(2) plotregion(margin(vlarge))

加入barbsize选项后我们就可以对箭头内部进行填充,并设置填充部分的大小,无此选项的话,箭头就只有外部轮廓线。
twoway pcarrowi 2 1 3 2 (3) "爬虫俱乐部" ,mlabsize(large) aspect(2) plotregion(margin(vlarge))

使用mlabsize我们可以使标注部分字体变得更大。

那么如何同时设置多个箭头和标注的大小呢?

twoway pcarrowi 2 2 2 4 (3) "3 o'clock" 2 2 3.4 2 (12) "12 o'clock" 2 2 1.5 0.6 (8) "8 o'clock", ///msize(large) barbsize(large) mlabsize(vlarge) aspect(1) headlabel plotregion(margin(vlarge))

在上边的程序中我们同时使用了三个选项,对箭头,填充部分和标注内容的大小都进行了定义,进一步,可以不可以分别定义每个箭头和标注的大小呢?当然是可以的!
twoway (pcarrowi 2 2 2 4 (3) "3 o'clock" ,msize(medium) aspect(1) mlabsize(large) headlabel plotregion(margin(vlarge))) ///(pcarrowi 2 2 3.4 2 (12) "12 o'clock",msize(medlarge) barbsize(medlarge) mlabsize(large) headlabel plotregion(margin(vlarge))) ///(pcarrowi 2 2 1.5 0.6 (8) "8 o'clock", msize(vlarge) barbsize(vlarge) mlabsize(large) headlabel plotregion(margin(vlarge)))

其实很简单,如案例所示分别将其用 ( ) 分隔起来就好了,这样每个箭头之间都是独立的部分,可以进行单独的操作。

02设置颜色和粗细

mcolor(mc) :箭头的颜色和不透明度,包含内外

mfcolor(mfc) :箭头"填充"颜色和不透明度

mlcolor(mlc) :箭头轮廓颜色和不透明度

其中颜色选项就不胜枚举了,常用的有:black、blue、gold、green、yellow等,其他更多选项可以通过 help colorstyle获取。

mlwidth(mlw) :箭头轮廓厚度(粗细)

其中选项从薄到厚有:none、vvvthin、vvthin、vthin、thin、medthin、medium、medthick、thick、vthick、vvthick、vvvthick

当然也能自定义厚度(粗细),help size可获取具体方式

mlstytle(mlsty) :轮廓厚度(粗细)和颜色

与上文类似,有p1-p15可供选择,更多样式选择可以通过help style 获取

同样的我们先来看如何设置单个箭头的颜色和粗细。

twoway pcarrowi 2 1 3 2 (6) "爬虫俱乐部", mcolor(red) msize(vlarge) aspect(2) plotregion(margin(vlarge))

twoway pcarrowi 2 1 3 2 (6) "爬虫俱乐部", mcolor(red) mfcolor(yellow) msize(vlarge) barbsize(large) aspect(2) plotregion(margin(vlarge))

这里需要注意的是mfcolor要与barbsize搭配使用,只有设置了箭头填充部分后才能给其定义颜色。而barbsize不能和mlwidth搭配使用,不然箭头加粗就会被箭头填充部分的内容覆盖掉。
twoway pcarrowi 2 1 3 2 (6) "爬虫俱乐部", mcolor(red) mlwidth(vthick) msize(vlarge) aspect(2) plotregion(margin(vlarge))

设置多个箭头的颜色和粗细如下:
twoway (pcarrowi 2 2 2 4 (3) "3 o'clock" ,mcolor(blue) mlwidth(thick) msize(medium) aspect(1) mlabsize(large) headlabel plotregion(margin(vlarge))) ///(pcarrowi 2 2 3.4 2 (12) "12 o'clock",mcolor(gold) mlwidth(vthick) msize(medlarge) barbsize(medlarge) mlabsize(large) headlabel plotregion(margin(vlarge))) ///(pcarrowi 2 2 1.5 0.6 (8) "8 o'clock", mcolor(red) mfcolor(gold) mlwidth(vthick) msize(vlarge) barbsize(vlarge) mlabsize(large) headlabel plotregion(margin(vlarge)))

这里需要注意的是mcolor(red)、mfcolor(gold)、mlwidth(vthick)三者同时出现时,箭头加粗就会被填充部分的内容覆盖掉了,颜色由mcolor设定为主。

03设置角度

mangle() :箭头的角度(箭头内角的大小)。括号里可以直接加入数字代指角度,比如 45 90 180,也可以输入 horizontal vertical 等。具体可见 help anglestyle

twoway pcarrowi 2 1 3 2 (3) "爬虫俱乐部",mangle(90) msize(vlarge) aspect(2) plotregion(margin(vlarge))

这里我们设置箭头角度为90后,可以看到它折叠为一条直线了,这里我们只是举一个极端的例子供大家学习,一般还是小角度的使用比较多。

04设置箭杆的样式

lstyle (lsty):线条整体风格

lpattern (lp):线条连接方式,实线、虚线等。其中选项有:solid  dash  dot  dash_dot  shortdash  longdash  blank 等

lwidth (lw):线条粗细

lcolor (lc):线条颜色

整体风格,粗细和颜色的设定可以参考前面的介绍。

twoway pcarrowi 2 1 3 2 (6) "爬虫俱乐部" , ///lp(dash_dot) lw(thick) lc(green) mlwidth(thick) mcolor(gold) msize(large) mlabsize(large) aspect(1) plotregion(margin(vlarge))

这样我们就通过命令设置了线条为交错的虚线,线条为粗,颜色为绿色。


五、综合案例

我们通过一个案例看具体如何使用这些具体的选项,先看一下前面举过的例子:

sysuse auto,cleartwoway qfitci mpg weight,stdf || scatter mpg weight,ms(O) || ///pcarrowi 41 2200 41 2060 (3) "VW Diesel" 31 3460 28 3280 (3) "Plymouth Arrow"35 2250 35 2070 (3) "Datsun 210 and Subaru", ///mstyle(p10) msize(huge) mlabsize(medium) mcolor(blue) mlwidth(thick) lp(dash) lw(thick) lc(gold) mangle(30) legend(order(1 2 3))

这里我们重新设置了箭头的大小,粗细和颜色,以及箭柱的连接方式,粗细和颜色,最后还设置了箭头的角度。通过刚刚介绍的这些选项我们可以自定义我们想要的内容。

我们再使用auto数据进行一个演示:

twoway scatter mpg weight if foreign==1 || lfit mpg weight if foreign==1||scatter mpg weight if foreign==0 || lfit mpg weight if foreign==0 ///|| pcarrowi 17 2550 20 2750 (5) /// 26 3050 23 2800 (5), ///mstyle(p14) msize(huge) barbsize(vlarge) mlabsize(huge) mcolor(gold) mlwidth(thick) mangle(20) lp(dash) lw(thick) lc(blue) ///text(16.5 2500 "Foreign" 26.8 3100 "Domestic")xtitle("weight") ytitle("mpg")legend(order(1 "Foreign" 2 "Foreign" 3 "Domestic" 4 "Domestic") row(1))

这里不同的就是,我们用text选项定义了文本的位置。

最后我们画一个有趣的案例:简易时钟。

clear all set obs 12 gen theta = 2*_pi*_n/12gen x = cos(theta)gen y = sin(theta)forvalues i = 1/12{local x`i' = x[`i']local y`i' = y[`i']}twoway (pcarrowi 0 0 -0.25 -0.5 (8) ,headlabel msize(large) lw(medthick) text(-0.6 -0.9 "8")) /// (pcarrowi 0 0 `x12' `y12' (12) "12" ,headlabel msize(large) lw(medthick)) /// (pcarrowi `x1' `y1' `x2' `y2',mstyle(sunflower)) /// (pcarrowi `x2' `y2' `x3' `y3',mstyle(sunflower)) /// (pcarrowi `x3' `y3' `x4' `y4',mstyle(sunflower)) /// (pcarrowi `x4' `y4' `x5' `y5',mstyle(sunflower)) /// (pcarrowi `x5' `y5' `x6' `y6',mstyle(sunflower)) /// (pcarrowi `x6' `y6' `x7' `y7',mstyle(sunflower)) /// (pcarrowi `x7' `y7' `x8' `y8',mstyle(sunflower)) /// (pcarrowi `x8' `y8' `x9' `y9',mstyle(sunflower)) /// (pcarrowi `x9' `y9' `x10' `y10',mstyle(sunflower)) /// (pcarrowi `x10' `y10' `x11' `y11',mstyle(sunflower)) /// (pcarrowi `x11' `y11' `x12' `y12',mstyle(sunflower)) /// (pcarrowi `x12' `y12' `x1' `y1',mstyle(sunflower)) /// ,aspect(1) plotregion(margin(vlarge)) legend(off)

首先我们生成12等分角,然后用cos和sin我们生成了相对应的坐标,接着我们将这些坐标首尾相连就形成了一个密闭的时钟表盘了,最后我们再用箭头绘制上时针和分针。

通过上述介绍我们可以看到小小箭头也大有文章可做,通过与不同的图形搭配,它既可以标注内容也可以画出一些有趣的图形。欢迎大家在此篇推文的基础上,再探索出更多的用法。

END

最后,我们为大家揭秘雪球网(https://xueqiu.com/)最新所展示的沪深证券和港股关注人数增长Top10。


腾讯课堂课程二维码








            


 对我们的推文累计打赏超过1000元,我们即可给您开具发票,发票类别为“咨询费”。用心做事,不负您的支持!











往期推文推荐
        Seminar丨荐仆贷款——19世纪中国的信任辅助贷款
       【技能篇】多进程队列间通信

        Seminar丨公司董事会的人才增长:来自中国的证据

        正则表达式--懒惰模式

        爬完独立董事的年薪,我的眼镜跌破了!        识别旅游“照骗”——看风景名胜是否名副其实        主成分分析的Python实现

正则表达式--贪婪模式

Seminar丨谁更重要:高管股权薪酬与财务报告欺诈DOS能量,超乎你想象!

爬虫实战丨走进哈利波特的魔法世界

数据集合并的新路子-frlink命令

Seminar丨附近的公司:利用卫星图像研究本地信息优势

线性同余法生成伪随机数 

[技能篇]多线程爬虫

“好哭”是衡量一部好电影的标准吗?

Stata&Python云端课程来啦!

带你了解Stata中的矩阵

Seminar|总统的朋友:政治关联与企业价值
爬虫实战 | 爬取中国天气网

爬虫实战 | 爬取东方财富网经济数据——以居民消费价格指数(CPI)为例

Seminar|媒体关联董事对融资和外部治理的影响神奇的组内交叉合并 PDF分章节转TXT并实现可视化——以胡景北知青日记1971至1978年为例

万物皆可开——shellout妙用

无处不在的系列配置项|从零开始的Pyecharts(三)

使用Python制作自动聊天机器人  

fillin一下,平衡回来~

order命令——快速改变变量顺序的利器 Ajax应用场景——以获取雪球网港股代码及公司名称为例

播放列表中的歌单排行 

在Stata中轻松运用program编写命令

Meta Analysis in Stata17      

关于我们 


   微信公众号“Stata and Python数据分析”分享实用的Stata、Python等软件的数据处理知识,欢迎转载、打赏。我们是由李春涛教授领导下的研究生及本科生组成的大数据处理和分析团队。

   武汉字符串数据科技有限公司一直为广大用户提供数据采集和分析的服务工作,如果您有这方面的需求,请发邮件到statatraining@163.com,或者直接联系我们的数据中台总工程司海涛先生,电话:18203668525,wechat: super4ht。海涛先生曾长期在香港大学从事研究工作,现为知名985大学的博士生,爬虫俱乐部网络爬虫技术和正则表达式的课程负责人。



此外,欢迎大家踊跃投稿,介绍一些关于Stata和Python的数据处理和分析技巧。

投稿邮箱:statatraining@163.com投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里
为作者署名,并有赏金分成。

2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到有关数据处理、分析等问题,可以在公众
号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存