如何创建一组具有链接(共享)x轴的图表,在缩放期间自动缩放所有"从"图的y轴?例如:
import matplotlib.pyplot as plt
fig = plt.figure()
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212, sharex=ax1)
ax1.plot([0,1])
ax2.plot([2,1])
plt.show()
Run Code Online (Sandbox Code Playgroud)
当我放大ax1时,这也会更新ax2的x轴(到目前为止一直很好),但我也希望ax2的y轴基于现在可见的数据范围进行自动缩放.所有自动缩放设置均已启用(默认设置).创建ax2后手动设置自动缩放设置没有帮助:
ax2.autoscale(enable=True, axis='y', tight=True)
ax2.autoscale_view(tight=True, scalex=False, scaley=True)
print ax2.get_autoscaley_on()
-> True
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
我试图用我的大型Python应用程序调试内存问题.大多数内存都在numpy由Python类管理的数组中,所以Heapy等没用,因为它们不考虑numpy数组中的内存.所以我尝试使用MacOSX(10.7.5)活动监视器(或者top如果你愿意)手动跟踪内存使用情况.我注意到以下奇怪的行为.在普通的python解释器shell(2.7.3)上:
import numpy as np # 1.7.1
# Activity Monitor: 12.8 MB
a = np.zeros((1000, 1000, 17)) # a "large" array
# 142.5 MB
del a
# 12.8 MB (so far so good, the array got freed)
a = np.zeros((1000, 1000, 16)) # a "small" array
# 134.9 MB
del a
# 134.9 MB (the system didn't get back the memory)
import gc
gc.collect()
# 134.9 MB
Run Code Online (Sandbox Code Playgroud)
无论我做什么,Python会话的内存占用量将永远不会再低于134.9 MB.所以我的问题是:
为什么数组的资源大于1000x1000x17x8字节(在我的系统上经验找到)正确地返回给系统,而较小数组的内存似乎永远被Python解释器所困? …
我最近尝试过,PyPy并对这种方法很感兴趣.我有很多Python的C扩展,它们都PyArray_DATA()用来获取指向numpy数组数据部分的指针.不幸的是,PyPy似乎没有numpypy在他们的cpyext模块中导出他们的数组的等价物,所以我尝试按照他们网站上的推荐使用ctypes.这推动了获取Python级别指针的任务.
似乎有两种方式:
import ctypes as C
p_t = C.POINTER(C.c_double)
def get_ptr_ctypes(x):
return x.ctypes.data_as(p_t)
def get_ptr_array(x):
return C.cast(x.__array_interface__['data'][0], p_t)
Run Code Online (Sandbox Code Playgroud)
只有第二个适用于PyPy,因此为了兼容性,选择很明确.对于CPython来说,两者都很慢,我的应用程序完全成为瓶颈!是否有快速便携的方法来获取此指针?或者是否有相当于PyArray_DATA()PyPy(可能没有文档)?
此问题与我之前的问题有关,当尝试从私有实例调用模板方法时出现编译器错误,这被指出与此问题有关:我在哪里以及为什么要放置"template"和"typename"关键字?
所以我读了这篇文章,我认为C++语言定义含糊不清,因此无法始终正确解析.在我的情况,得到的答复是,我需要a.template f<1>()在B::test()帮助解析器明白,这是处理的模板.精细.
但是,在阅读了所有这些之后,template如果碰巧有一个完全不相关的全局模板函数碰巧具有相同的名称,为什么解析器突然能够在没有关键字的情况下执行?这编译没有问题,并按预期运行:
#include <iostream>
template <int i>
void f() {std::cout << "f()\n";}
template <int N>
struct A {
template <int i>
void f() {std::cout << "A::f()\n";}
};
template <int N>
struct B {
A<N> a;
B(A<N>& a) : a(a) {}
void test() {
f<1>();
a.f<1>(); // compiles without 'template' keyword!
}
};
int main() {
A<2> a;
a.f<1>(); // works fine
B<2> b(a);
b.test();
}
Run Code Online (Sandbox Code Playgroud)
我发现全局函数必须:
f我正在重新评估将外部 C 库包装到 Python 中的不同方法。我很久以前就选择使用简单的 Python C API,它快速、简单、独立,而且正如我认为的那样,它是面向未来的。然后我偶然发现了PyPy,它显然不打算支持 CPython API,但将来可能会成为一个有趣的替代方案......因此我正在寻找一个更高级别的入口点。ctypes速度很慢,所以现在我回到了cython,它似乎正在努力支持 PyPy。
我的库有许多具有相同签名的函数,因此我广泛使用 C 预处理器宏来生成 Python 模块。我认为这在 cython 中会变得更加舒适,因为我可以访问整个 Python 语言。但是,我在为函数包装器编写工厂时遇到问题:
import cython
from numpy cimport ndarray, double_t
cimport my_c_library
cdef my_c_library.data D
ctypedef double_t DTYPE_t
cdef parse_args(ndarray[DTYPE_t] P, ndarray[DTYPE_t] x, ndarray[DTYPE_t] y):
D.n = P.size
D.m = x.size
D.P = <double*> P.data
D.x = <double*> x.data
D.y = <double*> y.data
def _fun_factory(name):
cpdef fun(ndarray[DTYPE_t] P, ndarray[DTYPE_t] x, ndarray[DTYPE_t] y):
parse_args(P, x, y)
getattr(my_c_library, name)(&D) …Run Code Online (Sandbox Code Playgroud) 我正在开发一个迭代器系列,其中所有迭代器类X都有X& operator++() {++x; return *this}共同点,因此将它放在一个公共基类中似乎是个好主意.不幸的是,返回类型会发生变化,因为它应该始终返回对派生类的引用.
以下说明了这个问题.我想f()工作,但唯一的解决方法我能想出是g()和h(),这是不令人满意的:
struct A {
A& f() {return *this;}
template <typename T>
T& g() {return *(T*)this;}
template <typename T>
T& h(T& unused) {return *(T*)this;}
};
struct B : A {
int x;
B(int x) : x(x) {}
};
int main() {
B b(12);
//B b1 = b.f(); // error: conversion from 'A' to non-scalar type 'B' requested
B b2 = b.g<B>(); // works
B b3 = …Run Code Online (Sandbox Code Playgroud) (如果你已经知道答案,这个问题只是另一个问题的重复!)
(请注意我的后续问题:如果存在具有相同名称的不相关全局模板函数,为什么不需要模板关键字?)
当我尝试使用这种结构编译模板化的C++代码时,在指定的行中出现编译器错误:
template <int N>
struct A {
template <int i>
void f() {};
};
template <int N>
struct B {
A<N> a;
B(A<N>& a) : a(a) {}
void test() {
a.f<1>(); // does not compile
}
};
int main() {
A<2> a;
a.f<1>(); // works fine
B<2> b(a);
b.test();
}
Run Code Online (Sandbox Code Playgroud)
g++ 说:
test2.cpp: In member function ‘void B<N>::test()’:
test2.cpp:14: error: expected primary-expression before ‘)’ token
test2.cpp: In member function ‘void B<N>::test() [with int N = 2]’: …Run Code Online (Sandbox Code Playgroud) 我刚刚得到以下构造的编译器错误:
size_t N = 10;
size_t Ntransforms = std::min(PySequence_Fast_GET_SIZE(__transforms), N);
Run Code Online (Sandbox Code Playgroud)
因为PySequence_Fast_GET_SIZE()实际上返回Py_ssize_t并被std::min()定义为
template <class T> const T& min (const T& a, const T& b);
Run Code Online (Sandbox Code Playgroud)
由于它需要相同类型的左值引用,我很惊讶我可以使用内联类型转换来修复它:
size_t Ntransforms = std::min((size_t)PySequence_Fast_GET_SIZE(__transforms), N);
Run Code Online (Sandbox Code Playgroud)
这个可以吗?如果是,它是否等同于显式代码:
size_t Ntransforms = PySequence_Fast_GET_SIZE(__transforms);
if (Ntransforms > N) Ntransforms = N;
Run Code Online (Sandbox Code Playgroud) c++ ×4
python ×4
numpy ×3
templates ×3
api ×1
c++11 ×1
ctypes ×1
cython ×1
inheritance ×1
matplotlib ×1
memory ×1
memory-leaks ×1
polymorphism ×1
pypy ×1