Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 智能计算图表刻度位置_Python_Math_Graph - Fatal编程技术网

Python 智能计算图表刻度位置

Python 智能计算图表刻度位置,python,math,graph,Python,Math,Graph,无论我在使用matplotlib、Open Flash Charts或其他图表框架,我最终都需要找到一种方法来设置x/y比例限制和间隔,因为内置程序不够智能(或者根本没有…) 只要在pylab(ipyhton-pylab)中尝试一下,就可以理解我的意思: In [1]: a, b, x = np.zeros(10), np.ones(10), np.arange(10) In [2]: plot(x, a); plot(x, b) 您将看到在其顶部和底部边界下隐藏了两条水平线的空框架网格 我

无论我在使用matplotlib、Open Flash Charts或其他图表框架,我最终都需要找到一种方法来设置x/y比例限制和间隔,因为内置程序不够智能(或者根本没有…)

只要在pylab(ipyhton-pylab)中尝试一下,就可以理解我的意思:

In [1]: a, b, x = np.zeros(10), np.ones(10), np.arange(10)

In [2]: plot(x, a); plot(x, b)
您将看到在其顶部和底部边界下隐藏了两条水平线的空框架网格

我想知道是否有一些算法(我可以移植到python中)可以巧妙地设置顶部和底部的y限制和步骤,并计算每多少个值显示x厚度

例如,假设我有475个度量值作为
(日期时间,温度)
作为
(x,y)

2011-01-15 10:45:00 < datetime < 2011-01-17 02:20:00
2011-01-15 10:45:00
(每5分钟一次)和

26.5<温度<28.3
我对这一特殊情况的建议是:


26.4以下是我多年来一直使用的方法,非常简单,效果也很好。请原谅我使用C语言,但将其翻译成Python应该并不困难

以下功能是必需的,来自Graphic Gems第1卷

double NiceNumber (const double Value, const int Round) {
  int    Exponent;
  double Fraction;
  double NiceFraction;

  Exponent = (int) floor(log10(Value));
  Fraction = Value/pow(10, (double)Exponent);

  if (Round) {
    if (Fraction < 1.5) 
      NiceFraction = 1.0;
    else if (Fraction < 3.0)
      NiceFraction = 2.0;
    else if (Fraction < 7.0)
      NiceFraction = 5.0;
    else
      NiceFraction = 10.0;
   }
  else {
    if (Fraction <= 1.0)
      NiceFraction = 1.0;
    else if (Fraction <= 2.0)
      NiceFraction = 2.0;
    else if (Fraction <= 5.0)
      NiceFraction = 5.0;
    else
      NiceFraction = 10.0;
   }

  return NiceFraction*pow(10, (double)Exponent);
 }

我在这里报告上述C代码的python版本,如果它对某人有帮助的话:

导入数学
def nice_编号(值,四舍五入=False):
''nice_number(value,round_u=False)->float''
指数=math.floor(math.log(值,10))
分数=值/10**指数
如果是圆形:
如果分数<1.5:
很好的分数=1。
elif分数<3:
很好的分数=2。
elif分数<7:
很好的分数=5。
其他:
很好的分数=10。
其他:

如果下面的分数是自动计算刻度的python代码,那么它需要数据范围和最大刻度数

例如:

auto_tick([-120, 580], max_tick=10, tf_inside=False)
Out[224]: array([-100.,   -0.,  100.,  200.,  300.,  400.,  500.])
auto_tick([-120, 580], max_tick=20, tf_inside=False)
Out[225]: array([-100.,  -50.,   -0.,   50.,  100.,  150.,  200.,  250.,  300., 350.,  400.,  450.,  500.,  550.])
下面是函数的Python代码

def auto_tick(数据范围,最大刻度=10,tf_inside=False):
"""
根据范围和最大刻度数自动计算最佳刻度的工具功能
:param data_range:数据范围,例如[0.1,0.5]
:param max_tick:最大刻度数,整数,默认为10
:param tf_inside:如果仅允许勾号在内部,则为真/假
:return:勾号列表
"""
数据范围=数据范围[1]-数据范围[0]
比例=10.0**np.楼层(np.log10(数据跨度))#数据比例为10,例如1、10、100、0.1、0.01。。。
列出_tick_size_nmlz=[5.0,2.0,1.0,0.5,0.2,0.1,0.05,0.02,0.01]#范围[1,10]内规范化数据的可能刻度大小
刻度大小\u nmlz=1.0#标准化数据的初始刻度大小
对于范围内的i(len(list_tick_size_nmlz)):#每个循环减少tick size,从而增加tick number
num_tick=data_span/scale/list_tick_size_nmlz[i]#当前刻度大小的刻度数
如果num_tick>max_tick:#如果tick过多,则中断循环
勾选大小=列表勾选大小[i-1]
打破
勾选大小=勾选大小nmlz*比例#勾选原始数据的大小
ticks=np.unique(np.arange(数据范围[0]/tick大小,数据范围[1]/tick大小)。round())*tick大小#ticks列表
如果tf_在内部:#如果只允许在给定范围内打勾
ticks=ticks[(ticks>=data_range[0])*(ticks,以下是in-TypeScript/JavaScript ES6的版本:

函数niceNumber(值:number,舍入=false){
常数指数=Math.floor(Math.log10(值));
常数分数=数值/数学功率(10,指数);
让分数:数字;
if(圆形){
如果(分数<1.5){
平均分数=1.0;
}否则如果(分数<3.0){
平均分数=2.0;
}否则如果(分数<7.0){
平均分数=5.0;
}否则{
平均分数=10.0;
}
}否则{

如果(分数)我使用得越多,我就越觉得它真的很聪明,谢谢分享。你可以在JavaScript中使用
Math.log10()。
      //Input parameters
  double AxisStart = 26.5;
  double AxisEnd   = 28.3;
  double NumTicks  = 10;

  double AxisWidth;
  double NewAxisStart;
  double NewAxisEnd;
  double NiceRange;
  double NiceTick;

    /* Check for special cases */
  AxisWidth = AxisEnd - AxisStart;
  if (AxisWidth == 0.0) return (0.0);

    /* Compute the new nice range and ticks */
  NiceRange = NiceNumber(AxisEnd - AxisStart, 0);
  NiceTick = NiceNumber(NiceRange/(NumTicks - 1), 1);

    /* Compute the new nice start and end values */
  NewAxisStart = floor(AxisStart/NiceTick)*NiceTick;
  NewAxisEnd = ceil(AxisEnd/NiceTick)*NiceTick;

  AxisStart = NewAxisStart; //26.4
  AxisEnd = NewAxisEnd;     //28.4
>>> nice_bounds(26.5, 28.3)
(26.4, 28.4, 0.2)
function nice_number(value, round_){
    //default value for round_ is false
    round_ = round_ || false;
    // :latex: \log_y z = \frac{\log_x z}{\log_x y}
    var exponent = Math.floor(Math.log(value) / Math.log(10));
    var fraction = value / Math.pow(10, exponent);

    if (round_)
        if (fraction < 1.5)
            nice_fraction = 1.
        else if (fraction < 3.)
            nice_fraction = 2.
        else if (fraction < 7.)
            nice_fraction = 5.
        else
            nice_fraction = 10.
    else
        if (fraction <= 1)
            nice_fraction = 1.
        else if (fraction <= 2)
            nice_fraction = 2.
        else if (fraction <= 5)
            nice_fraction = 5.
        else
            nice_fraction = 10.

    return nice_fraction * Math.pow(10, exponent)
}

function nice_bounds(axis_start, axis_end, num_ticks){
    //default value is 10
    num_ticks = num_ticks || 10;
    var axis_width = axis_end - axis_start;

    if (axis_width == 0){
        axis_start -= .5
        axis_end += .5
        axis_width = axis_end - axis_start
    }

    var nice_range = nice_number(axis_width);
    var nice_tick = nice_number(nice_range / (num_ticks -1), true);
    var axis_start = Math.floor(axis_start / nice_tick) * nice_tick;
    var axis_end = Math.ceil(axis_end / nice_tick) * nice_tick;
    return {
        "min": axis_start,
        "max": axis_end,
        "steps": nice_tick
    }
}
auto_tick([-120, 580], max_tick=10, tf_inside=False)
Out[224]: array([-100.,   -0.,  100.,  200.,  300.,  400.,  500.])
auto_tick([-120, 580], max_tick=20, tf_inside=False)
Out[225]: array([-100.,  -50.,   -0.,   50.,  100.,  150.,  200.,  250.,  300., 350.,  400.,  450.,  500.,  550.])