Чтобы показать, как получить правильный размер легенды цветовой шкалы, сопровождающей карту, созданную методом geopandas
plot (), я использую встроенный набор данных naturalearth_lowres . Рабочий код выглядит следующим образом.
import matplotlib.pyplot as plt
import geopandas as gpd
world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
world = world[(world.name != "Antarctica") & (world.name != "Fr. S. Antarctic Lands")] # exclude 2 no-man lands
# plot as usual, grab the axes 'ax' returned by the plot
colormap = "copper_r" # add _r to reverse the colormap
ax = world.plot(column='pop_est', cmap=colormap, \
figsize=[12,9], \
vmin=min(world.pop_est), vmax=max(world.pop_est))
# map marginal/face deco
ax.set_title('World Population')
ax.grid()
# colorbar will be created by ...
fig = ax.get_figure()
# add colorbar axes to the figure
# here, need trial-and-error to get [l,b,w,h] right
# l:left, b:bottom, w:width, h:height; in normalized unit (0-1)
cbax = fig.add_axes([0.95, 0.3, 0.03, 0.39])
cbax.set_title('Population')
sm = plt.cm.ScalarMappable(cmap=colormap, \
norm=plt.Normalize(vmin=min(world.pop_est), vmax=max(world.pop_est)))
# at this stage,
# 'cbax' is just a blank axes, with un needed labels on x and y axes
# blank-out the array of the scalar mappable 'sm'
sm._A = []
# draw colorbar into 'cbax'
fig.colorbar(sm, cax=cbax, format="%d")
# dont use: plt.tight_layout()
plt.show()
Прочитайте комментарии в коде для полезной информации.
Я соглашаюсь с Guishu и MSalters. Даже если это не для хода программирования, может быть хорошо подражать более тесно взгляду математики (например, vector3 = vector1+vector2 и т.д.).
То, что Вы могли также сделать, должно использовать копию на записи (refounting быть логическим следствием), но только внутренне. Это может дать Вам достаточно быстро присвоения, устранить управление "кучей" на клиентском и подобии математической нотации.
Обратите внимание, однако, что существуют математические библиотеки, доступные для C++ (TNT, первое, что пришло на ум). Вы рассматривали базирование Вашей работы над этим?
Пользователи моих классов будут людьми, которые плохо знакомы с языком.
Ваш класс разработан для хода программирования?
Если это верно, я избегал бы использования указателей и использовал бы только конструкторов копии / присваивание:
Я рекомендовал бы intrusive_ptr вместо shared_ptr для объектов, которыми можно управлять для лучшей производительности и удобства использования, поскольку можно присвоить необработанный указатель на intrusive_ptr позже, потому что подсчет ссылок встраивается в объект.
То, что Вы попробовали, должно было перегрузить оператор для скалярных типов. C++ не позволяет Вам делать это за исключением перечислений (не по существу, что оператор = должен быть участником). По крайней мере один из типов должен быть определяемым пользователем типом. Таким образом то, что Вы хотите сделать, должно перенести необработанный указатель в определяемый пользователем класс, который конструктор перегрузок, скопируйте конструктора, скопируйте оператор присваивания и деструктор надлежащего подсчета ссылок. Это - идеальная ситуация для boost::shared_ptr
, который делает точно что:
boost::shared_ptr<CCurve> c1(new CBezier(pts));
То же соглашение с поверхностями:
CVecList pts;
// ...
boost::shared_ptr<CCurve> f(new CBezier(pts));
pts.Clear();
// ...
boost::shared_ptr<CCurve> g(new CBezier(pts));
// Mixed surface: S(u,v) = (1-v)f(u) + vg(u)
boost::shared_ptr<CSurface> s(new CMixed(f,g));
Несите вокруг того интеллектуального указателя, и он будет автоматически управлять временем жизни резкого для возражения: Если последняя копия указателя выходит из объема, объект указал, освобожден. shared_ptr
разработан для EA. Постарайтесь не работать с необработанными указателями так, как Вы можете. Взгляните на те интеллектуальные указатели, они упростят Ваших программистов, живых с C++ :)
Править: Если Вы собираетесь перенести shared_ptr, можно сделать настолько использующий pimpl (дескриптор/тело) идиома:
/* ---- wrapper in header file bezier.hpp */
struct CBezier {
CBezier(CVecList const& list);
void do_calc();
// ...
private:
struct CBezierImpl;
boost::shared_ptr<CBezierImpl> p;
};
/* ---- implementation file bezier.cpp */
// private implementation
struct CBezier::CBezierImpl {
CBezierImpl(CVecList const& list);
void do_calc();
// ...
};
CBezier::CBezier(CVecList const& list)
:p(new CBezierImpl(list)) {
}
void CBezier::do_calc() {
// delegate to pimpl
p->do_calc();
}
// ...
Если Вы разрабатываете математическую библиотеку, проводите много времени, думая, могут ли Ваши классы быть похожими на интервал или станд.:: комплекс. То есть имейте значения, ведут себя как значения. Например.
std::vector<math::point3d> pts;
pts.push_back(math::point3d(0,0,0));
pts.push_back(math::point3d(110,0,0));
pts.push_back(math::point3d(0,100,0));
pts.push_back(math::point3d(0,0,100));
CCurve c1 = make_bezier(pts);