强制y轴从0开始,并且仍使用自动标签

发布于 2025-01-24 05:34:40 字数 1397 浏览 0 评论 0原文

我有一个y min的图,其最低速度远高于0。但是我想将0作为y轴的最小值,但仍然具有stata 自动创建均值均匀的y轴标签。

这是基线:

sysuse auto2, clear
scatter turn displacement

这产生:

这几乎是我想要的,除了y范围不是从0开始。

基于nick Cox的答案( https://www.statalist.org/forums/forums/forums/forums/通用 - 史塔省/常规/1598753-force-chart-y轴 - 轴 - 启动 - at-0 ),我修改代码为:

scatter turn displacement, yscale(range(0 .)) ylabel(0)

这成功在0处启动y轴,但是除了0之外,标签消失了:

”在此处输入图像说明“

我继续删除`ylabel(0):

scatter turn displacement, yscale(range(0 .)) 

这会产生相反的问题 - y轴标签与第一个图中相同。

如何使Stata从0到最大产生Y轴标签?例如,0、10、20、30、40、50-重要的是,我有很多图,并且需要一个自动确定确切值的解决方案,而无需我输入y max等。我选择10、20,...,50,但Stata。

I have a plot whose y min starts well above 0. But I want to include 0 as the min of the y-axis and still have Stata automatically create evenly-spaced y-axis labels.

Here is the baseline:

sysuse auto2, clear
scatter turn displacement

This produces:
enter image description here

This is almost what I want, except that the y range does not start at 0.

Based on this answer by Nick Cox (https://www.statalist.org/forums/forum/general-stata-discussion/general/1598753-force-chart-y-axis-to-start-at-0), I modify the code to be:

scatter turn displacement, yscale(range(0 .)) ylabel(0)

This succeeds in starting the y-axis at 0, but the labeling besides 0 goes away:

enter image description here

I proceed to remove `ylabel(0):

scatter turn displacement, yscale(range(0 .)) 

This produces the opposite problem - the y-axis labels are the same as in the first plot.

How can I have Stata automatically produce the y-axis labels from 0 to the max? For instance, 0, 10, 20, 30, 40, 50 - importantly, though, I have many plots and need a solution that determines the exact values automatically, without needing me to input the y max, etc. So it would not be me who chooses 10, 20, ..., 50, but Stata.

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

羞稚 2025-01-31 05:34:40

巧合的是,我一直在这个领土上掌握指挥。这是一个可再现的例子。

sysuse auto, clear
summarize turn, meanonly
local max = r(max) 
nicelabels 0 `max', local(yla)
* shows 0 20 40 60
scatter turn displacement, yla(`yla', ang(h))
nicelabels 0 `max', local(yla) nvals(10)
* shows 0 10 20 30 40 50 60
scatter turn displacement, yla(`yla', ang(h))

其中Nicelabels目前为此代码。

*! 1.0.0 NJC 25 April 2022 
program nicelabels           
    /// fudge() undocumented 
    version 9

    gettoken first 0 : 0, parse(" ,")  

    capture confirm numeric variable `first' 

    if _rc == 0 {
        // syntax varname(numeric), Local(str) [ nvals(int 5) tight Fudge(real 0) ] 

        syntax [if] [in] , Local(str) [ nvals(int 5) tight Fudge(real 0) ] 
        local varlist `first'  

        marksample touse 
        quietly count if `touse'    
        if r(N) == 0 exit 2000 
    } 
    else { 
        // syntax #1 #2 , Local(str) [ nvals(int 5) tight Fudge(real 0) ] 

        confirm number `first' 
        gettoken second 0 : 0, parse(" ,") 
        syntax , Local(str) [ nvals(int 5) tight Fudge(real 0) ]
 
        if _N < 2 { 
            preserve 
            quietly set obs 2 
        }
    
        tempvar varlist touse 
        gen double `varlist' = cond(_n == 1, `first', `second') 
        gen byte `touse' = _n <= 2 
    }   

    su `varlist' if `touse', meanonly
    local min = r(min) - (r(max) - r(min)) * `fudge'/100 
    local max = r(max) + (r(max) - r(min)) * `fudge'/100 
 
    local tight = "`tight'" == "tight"
    mata: nicelabels(`min', `max', `nvals', `tight') 

    di "`results'"
    c_local `local' "`results'"
end  

mata : 

void nicelabels(real min, real max, real nvals, real tight) { 
    if (min == max) {
        st_local("results", min) 
        exit(0) 
    }

    real range, d, newmin, newmax
    colvector nicevals 
    range = nicenum(max - min, 0) 
    d = nicenum(range / (nvals - 1), 1)
    newmin = tight == 0 ? d * floor(min / d) : d * ceil(min / d)
    newmax = tight == 0 ? d * ceil(max / d) : d * floor(max / d)  
    nvals = 1 + (newmax - newmin) / d 
    nicevals = newmin :+ (0 :: nvals - 1) :* d  
    st_local("results", invtokens(strofreal(nicevals')))   
}

real nicenum(real x, real round) { 
    real expt, f, nf 
    
    expt = floor(log10(x)) 
    f = x / (10^expt) 
    
    if (round) { 
        if (f < 1.5) nf = 1 
        else if (f < 3) nf = 2
        else if (f < 7) nf = 5
        else nf = 10 
    }
    else { 
        if (f <= 1) nf = 1 
        else if (f <= 2) nf = 2 
        else if (f <= 5) nf = 5 
        else nf = 10 
    }

    return(nf * 10^expt)
}

end 

编辑

如果您去,

sysuse auto, clear 
summarize turn, meanonly 
local max = r(max) 
scatter turn displacement, yla(0(10)`max', ang(h))
scatter turn displacement, yla(0(20)`max', ang(h))

您会得到很好的解决方案。显然,在这种情况下,我们需要知道10或20是要使用的步骤。使用您自己的食谱将有良好的宽度来计算良好的宽度。

编辑1022年5月10日,

已修订和记录的Nicelabels现在可以从SSC下载。

编辑2 28 2023年9月28日,现在可以访问 /em>纸

By coincidence, I have been working on a command in this territory. Here is a reproducible example.

sysuse auto, clear
summarize turn, meanonly
local max = r(max) 
nicelabels 0 `max', local(yla)
* shows 0 20 40 60
scatter turn displacement, yla(`yla', ang(h))
nicelabels 0 `max', local(yla) nvals(10)
* shows 0 10 20 30 40 50 60
scatter turn displacement, yla(`yla', ang(h))

where nicelabels is at present this code.

*! 1.0.0 NJC 25 April 2022 
program nicelabels           
    /// fudge() undocumented 
    version 9

    gettoken first 0 : 0, parse(" ,")  

    capture confirm numeric variable `first' 

    if _rc == 0 {
        // syntax varname(numeric), Local(str) [ nvals(int 5) tight Fudge(real 0) ] 

        syntax [if] [in] , Local(str) [ nvals(int 5) tight Fudge(real 0) ] 
        local varlist `first'  

        marksample touse 
        quietly count if `touse'    
        if r(N) == 0 exit 2000 
    } 
    else { 
        // syntax #1 #2 , Local(str) [ nvals(int 5) tight Fudge(real 0) ] 

        confirm number `first' 
        gettoken second 0 : 0, parse(" ,") 
        syntax , Local(str) [ nvals(int 5) tight Fudge(real 0) ]
 
        if _N < 2 { 
            preserve 
            quietly set obs 2 
        }
    
        tempvar varlist touse 
        gen double `varlist' = cond(_n == 1, `first', `second') 
        gen byte `touse' = _n <= 2 
    }   

    su `varlist' if `touse', meanonly
    local min = r(min) - (r(max) - r(min)) * `fudge'/100 
    local max = r(max) + (r(max) - r(min)) * `fudge'/100 
 
    local tight = "`tight'" == "tight"
    mata: nicelabels(`min', `max', `nvals', `tight') 

    di "`results'"
    c_local `local' "`results'"
end  

mata : 

void nicelabels(real min, real max, real nvals, real tight) { 
    if (min == max) {
        st_local("results", min) 
        exit(0) 
    }

    real range, d, newmin, newmax
    colvector nicevals 
    range = nicenum(max - min, 0) 
    d = nicenum(range / (nvals - 1), 1)
    newmin = tight == 0 ? d * floor(min / d) : d * ceil(min / d)
    newmax = tight == 0 ? d * ceil(max / d) : d * floor(max / d)  
    nvals = 1 + (newmax - newmin) / d 
    nicevals = newmin :+ (0 :: nvals - 1) :* d  
    st_local("results", invtokens(strofreal(nicevals')))   
}

real nicenum(real x, real round) { 
    real expt, f, nf 
    
    expt = floor(log10(x)) 
    f = x / (10^expt) 
    
    if (round) { 
        if (f < 1.5) nf = 1 
        else if (f < 3) nf = 2
        else if (f < 7) nf = 5
        else nf = 10 
    }
    else { 
        if (f <= 1) nf = 1 
        else if (f <= 2) nf = 2 
        else if (f <= 5) nf = 5 
        else nf = 10 
    }

    return(nf * 10^expt)
}

end 

EDIT

If you go

sysuse auto, clear 
summarize turn, meanonly 
local max = r(max) 
scatter turn displacement, yla(0(10)`max', ang(h))
scatter turn displacement, yla(0(20)`max', ang(h))

you get good solutions. Clearly in this case we need to know that 10 or 20 is a step size to use. There would be scope to calculate a good width programmatically using your own recipe.

EDIT 10 May 2022

A revised and documented nicelabels is now downloadable from SSC.

EDIT 2 28 Sept 2023 A write-up is now accessible in this Stata Journal paper.

划一舟意中人 2025-01-31 05:34:40

尼克的解决方案更好,但是粗糙,简单的解决方案是绘制另一个在0或接近0的系列,并且可能是看不见的。例如:

sysuse auto2, clear
gen zero = 0 
twoway (scatter turn displacement) ///
       (scatter zero displacement , mcolor(none) ) , ///
       legend(off)                                       /* or legend(order(1))   */

但是需要注意传奇。

Nick's solution is better, but a crude and simple solution is to plot another series that is at or near 0, and it could be invisible. For example:

sysuse auto2, clear
gen zero = 0 
twoway (scatter turn displacement) ///
       (scatter zero displacement , mcolor(none) ) , ///
       legend(off)                                       /* or legend(order(1))   */

But care would need to be taken of the legend.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文