Рисунок на фигуре на фигуре
Я экспериментирую с matplotlib
чтобы нарисовать фигуры в цифрах. Поскольку квадраты – самые прямые, чтобы рисовать, я начал с них. В конце я хочу написать генератор для многоугольников с определенной шириной. В данном примере это будет четырехугольный многоугольник с прямыми углами и шириной 1.
Мой текущий код показывает следующее, которое как и ожидалось, так и почти по желанию.
Обратите внимание, что существует строка между 2,2
и 2,3
которая, как я думаю, может быть удалена, если это делается с использованием правильного алгоритма вместо текущего кода.
Краткое изложение вышесказанного – квадрат в коробке в двух коробках с амплитудой, увеличивающейся с 1
, предполагая, что большие коробки «отстают» от остальных коробок.
Метод, которым я написал код, производящий выше, является, ну, на самом деле, не функцией. Это чертовски уродливая коллекция очков, которые напоминают полые квадраты.
import matplotlib.path as mpath import matplotlib.patches as mpatches import matplotlib.pyplot as plt fig, ax = plt.subplots() INNER_AMPLITUDE = 1.0 OUTER_AMPLITUDE = 3.0 Path_in = mpath.Path path_in_data = [ (Path_in.MOVETO, (INNER_AMPLITUDE, -INNER_AMPLITUDE)), (Path_in.LINETO, (-INNER_AMPLITUDE, -INNER_AMPLITUDE)), (Path_in.LINETO, (-INNER_AMPLITUDE, INNER_AMPLITUDE)), (Path_in.LINETO, (INNER_AMPLITUDE, INNER_AMPLITUDE)), (Path_in.CLOSEPOLY, (INNER_AMPLITUDE, -INNER_AMPLITUDE)), ] codes, verts = zip(*path_in_data) path_in = mpath.Path(verts, codes) patch_in = mpatches.PathPatch(path_in, facecolor='g', alpha=0.3) ax.add_patch(patch_in) x, y = zip(*path_in.vertices) line, = ax.plot(x, y, 'go-') Path_out = mpath.Path path_out_data = [ (Path_out.MOVETO, (OUTER_AMPLITUDE, -OUTER_AMPLITUDE)), (Path_out.LINETO, (-OUTER_AMPLITUDE, -OUTER_AMPLITUDE)), (Path_out.LINETO, (-OUTER_AMPLITUDE, OUTER_AMPLITUDE)), (Path_out.LINETO, (OUTER_AMPLITUDE, OUTER_AMPLITUDE)), (Path_out.LINETO, (OUTER_AMPLITUDE, OUTER_AMPLITUDE-INNER_AMPLITUDE)), (Path_out.LINETO, (-(OUTER_AMPLITUDE-INNER_AMPLITUDE), OUTER_AMPLITUDE-INNER_AMPLITUDE)), (Path_out.LINETO, (-(OUTER_AMPLITUDE-INNER_AMPLITUDE), -(OUTER_AMPLITUDE-INNER_AMPLITUDE))), (Path_out.LINETO, (OUTER_AMPLITUDE-INNER_AMPLITUDE, -(OUTER_AMPLITUDE-INNER_AMPLITUDE))), (Path_out.LINETO, (OUTER_AMPLITUDE-INNER_AMPLITUDE, OUTER_AMPLITUDE-INNER_AMPLITUDE)), (Path_out.LINETO, (OUTER_AMPLITUDE, OUTER_AMPLITUDE-INNER_AMPLITUDE)), (Path_out.CLOSEPOLY, (OUTER_AMPLITUDE, OUTER_AMPLITUDE-INNER_AMPLITUDE)), ] codes, verts = zip(*path_out_data) path_out = mpath.Path(verts, codes) patch_out = mpatches.PathPatch(path_out, facecolor='r', alpha=0.3) ax.add_patch(patch_out) plt.title('Square in a square in a square') ax.grid() ax.axis('equal') plt.show()
Обратите внимание, что я рассматриваю эту не по теме для обзора кода, так как я ищу расширение моей функциональности, а не просто переписывание, которое соответствует лучшим практикам. Я чувствую, что делаю это совершенно неправильно. Прежде всего.
Как рисовать полигоны с определенной шириной с использованием matplotlib
, предполагая, что полигон будет окружен снаружи полосой того же вида и, по крайней мере, такой же ширины и полностью заполнен внутри?
- В чем разница между «pylab» и «matplotlib.pyplot»?
- формат метки оси matplotlib
- OSX Как перенести окно Matplotlib на передний план?
- matplotlib axes.clear () одинарных двойников не очищает вторую метку оси Y
- Matplotlib pyplot.title (строка) возвращает ошибку
Обработка полигонов исключительно в matplotlib может быть довольно утомительной. К счастью, для таких операций есть очень хорошая библиотека: стройная . Для ваших целей функция parallel_offset
– это путь. ring1
интересующих вас полигонов определяются ring1
, ring2
и ring3
:
import numpy as np import matplotlib.pyplot as plt import shapely.geometry as sg from descartes.patch import PolygonPatch # if I understood correctly you mainly need the difference d here INNER_AMPLITUDE = 0.1 OUTER_AMPLITUDE = 0.2 d = OUTER_AMPLITUDE - INNER_AMPLITUDE # fix seed, for reproducability np.random.seed(11111) # a function to produce a "random" polygon def random_polygon(): nr_p = np.random.randint(7,15) angle = np.sort(np.random.rand(nr_p)*2*np.pi) dist = 0.3*np.random.rand(nr_p) + 0.5 return np.vstack((np.cos(angle)*dist, np.sin(angle)*dist)).T # your input polygon p = random_polygon() # create a shapely ring object ring1 = sg.LinearRing(p) ring2 = ring1.parallel_offset(d, 'right', join_style=2, mitre_limit=10.) ring3 = ring1.parallel_offset(2*d, 'right', join_style=2, mitre_limit=10.) # revert the third ring. This is necessary to use it to procude a hole ring3.coords = list(ring3.coords)[::-1] # inner and outer polygon inner_poly = sg.Polygon(ring1) outer_poly = sg.Polygon(ring2, [ring3]) # create the figure fig, ax = plt.subplots(1) # convert them to matplotlib patches and add them to the axes ax.add_patch(PolygonPatch(inner_poly, facecolor=(0,1,0,0.4), edgecolor=(0,1,0,1), linewidth=3)) ax.add_patch(PolygonPatch(outer_poly, facecolor=(1,0,0,0.4), edgecolor=(1,0,0,1), linewidth=3)) # cosmetics ax.set_aspect(1) plt.axis([-1.5, 1.5, -1.5, 1.5]) plt.grid() plt.show()
Результат:
- numpy polyfit, проходящий через 0
- Джанго. Почему шаблоны администратора входят в базовую папку вместо mysite?
- складывание цветовых палитр
- Как я могу воссоздать эффект опции «-pylab» IPython со сценарием?
- Matplotlib демонстрирует ярлыки x-tick, перекрывающиеся, несмотря на все усилия
- Ошибка компиляции ld: библиотека не найдена для -lgcc_ext в MacOSX
- matplotlib: одноцветная цветовая палитра с насыщением
- Поиск элемента в одном массиве, соответствующего максимальному значению в другом
- знак вкладки pyplot
- Размещение графика в главном окне Tkinter в Python
- Построение круговой диаграммы в matplotlib под определенным углом с помощью ГРП на клиньях