Mapa baseado em cluster randômico¶
In [3]:
Copied!
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from scipy.spatial import ConvexHull, convex_hull_plot_2d
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs
from scipy.spatial import ConvexHull, convex_hull_plot_2d
In [4]:
Copied!
X, y = make_blobs(n_samples=300, centers=7, n_features=2, random_state=111)
print(y)
min_val = np.min(X)
if min_val < 0:
X_shifted = X + abs(min_val)
else:
X_shifted = X # No shift needed if already non-negative
X = X_shifted
fig, ax = plt.subplots(figsize=(9, 5), layout='constrained')
ax.scatter(X[:, 0], X[:, 1], c=y, cmap='viridis')
ax.set_title("Three normally-distributed clusters")
X, y = make_blobs(n_samples=300, centers=7, n_features=2, random_state=111)
print(y)
min_val = np.min(X)
if min_val < 0:
X_shifted = X + abs(min_val)
else:
X_shifted = X # No shift needed if already non-negative
X = X_shifted
fig, ax = plt.subplots(figsize=(9, 5), layout='constrained')
ax.scatter(X[:, 0], X[:, 1], c=y, cmap='viridis')
ax.set_title("Three normally-distributed clusters")
[5 5 3 6 2 1 3 4 1 2 5 5 3 1 0 0 5 2 6 5 3 6 4 4 3 1 0 4 0 0 1 4 3 5 0 3 4 5 1 2 3 5 6 2 2 1 2 0 1 5 5 3 3 4 2 1 3 6 4 1 1 4 1 0 6 5 5 0 4 1 1 0 0 1 1 5 6 5 4 1 2 6 0 5 0 5 0 1 3 5 6 4 0 5 1 1 1 6 3 0 2 6 6 5 6 6 3 2 4 1 6 6 3 5 1 2 3 5 0 2 1 6 2 1 4 3 6 5 3 0 4 4 2 1 5 0 1 2 0 3 1 6 2 1 2 6 4 1 3 4 4 5 6 0 5 6 1 3 4 5 3 0 2 3 6 4 5 2 2 2 0 6 5 5 2 4 4 3 2 2 0 4 3 6 6 5 3 4 3 2 4 4 2 2 3 5 4 1 0 0 6 1 2 3 0 3 1 2 1 0 6 4 4 0 6 5 4 0 3 6 1 2 4 4 5 3 2 6 6 0 5 2 6 2 0 3 3 1 0 4 5 1 2 3 1 3 1 0 4 3 5 6 2 6 2 5 6 2 0 4 0 2 0 3 2 0 0 5 1 5 4 4 6 5 1 4 3 0 5 3 1 6 2 6 2 3 3 6 5 4 6 0 0 2 4 0 3 6 4 4]
Out[4]:
Text(0.5, 1.0, 'Three normally-distributed clusters')
asdasd
In [5]:
Copied!
from matplotlib.collections import PatchCollection
from matplotlib.patches import Polygon
# Generate the data with 5 clusters
# X, y = make_blobs(centers=5, cluster_std=0.8, random_state=1234)
fig2, ax2 = plt.subplots(figsize=(9, 5), layout='constrained')
# Create a scatter plot of the original data points
# ax2.plot(X[:, 0], X[:, 1], 'bo')
ax2.scatter(X[:, 0], X[:, 1], c=y, cmap='viridis')
ax2.set_title("Convex Hull for Each Cluster")
patches = []
# Find and plot the convex hull for each cluster
for i in range(len(X)):
# Select the points belonging to the current cluster
points = X[y == i]
# Ensure there are at least 3 points to form a hull
if len(points) >= 3:
# Compute the convex hull
hull = ConvexHull(points)
# print(hull)
# ax2.plot(points[:, 0], points[:, 1], 'bo')
# for simplex in hull.simplices:
# ax2.plot(points[simplex, 0], points[simplex, 1], 'k-')
# Get the vertices of the hull
hull_vertices = points[hull.vertices]
# To close the polygon, append the first vertex to the end
closed_hull_vertices = np.vstack([hull_vertices, hull_vertices[0]])
# print(closed_hull_vertices)
polygon = Polygon(closed_hull_vertices, closed=True)
patches.append(polygon)
print(polygon)
# Plot the convex hull lines
ax2.plot(closed_hull_vertices[:, 0], closed_hull_vertices[:, 1], 'k-', lw=2)
# Display the plot
plt.show()
from matplotlib.collections import PatchCollection
from matplotlib.patches import Polygon
# Generate the data with 5 clusters
# X, y = make_blobs(centers=5, cluster_std=0.8, random_state=1234)
fig2, ax2 = plt.subplots(figsize=(9, 5), layout='constrained')
# Create a scatter plot of the original data points
# ax2.plot(X[:, 0], X[:, 1], 'bo')
ax2.scatter(X[:, 0], X[:, 1], c=y, cmap='viridis')
ax2.set_title("Convex Hull for Each Cluster")
patches = []
# Find and plot the convex hull for each cluster
for i in range(len(X)):
# Select the points belonging to the current cluster
points = X[y == i]
# Ensure there are at least 3 points to form a hull
if len(points) >= 3:
# Compute the convex hull
hull = ConvexHull(points)
# print(hull)
# ax2.plot(points[:, 0], points[:, 1], 'bo')
# for simplex in hull.simplices:
# ax2.plot(points[simplex, 0], points[simplex, 1], 'k-')
# Get the vertices of the hull
hull_vertices = points[hull.vertices]
# To close the polygon, append the first vertex to the end
closed_hull_vertices = np.vstack([hull_vertices, hull_vertices[0]])
# print(closed_hull_vertices)
polygon = Polygon(closed_hull_vertices, closed=True)
patches.append(polygon)
print(polygon)
# Plot the convex hull lines
ax2.plot(closed_hull_vertices[:, 0], closed_hull_vertices[:, 1], 'k-', lw=2)
# Display the plot
plt.show()
Polygon8((16.5064, 4.98898) ...) Polygon9((10.1552, 19.7447) ...) Polygon8((5.68945, 5.89569) ...) Polygon9((0, 9.24407) ...) Polygon8((9.30574, 7.48122) ...) Polygon8((24.7459, 6.43761) ...) Polygon9((4.51009, 13.3414) ...)
In [6]:
Copied!
import matplotlib
from matplotlib.collections import PatchCollection
from matplotlib.patches import Polygon
import matplotlib.pyplot as plt
fig3, ax3 = plt.subplots(1)
cmap = plt.get_cmap('terrain')
colors = cmap(len(X)) # convert nfloors to colors that we can use later
# patches = []
collection = PatchCollection(patches, cmap=matplotlib.cm.jet)
ax3.add_collection(collection)
collection.set_color(colors)
collection.set_edgecolor('k')
collection.set_clim([0, 50])
ax3.autoscale_view()
fig3.set_size_inches(9.5, 5.5)
#ax.set_facecolor('xkcd:sea blue')
# plt.axis('off')
plt.show()
# fig3.savefig("map2.png", dpi=fig.dpi, transparent=True)
import matplotlib
from matplotlib.collections import PatchCollection
from matplotlib.patches import Polygon
import matplotlib.pyplot as plt
fig3, ax3 = plt.subplots(1)
cmap = plt.get_cmap('terrain')
colors = cmap(len(X)) # convert nfloors to colors that we can use later
# patches = []
collection = PatchCollection(patches, cmap=matplotlib.cm.jet)
ax3.add_collection(collection)
collection.set_color(colors)
collection.set_edgecolor('k')
collection.set_clim([0, 50])
ax3.autoscale_view()
fig3.set_size_inches(9.5, 5.5)
#ax.set_facecolor('xkcd:sea blue')
# plt.axis('off')
plt.show()
# fig3.savefig("map2.png", dpi=fig.dpi, transparent=True)
In [7]:
Copied!
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
from perlin_noise import PerlinNoise
def add_perlin_noise_to_polygon(polygon, noise_generator, amplitude=0.1, frequency=10, num_subdivisions=20):
"""
Applies Perlin noise to the perimeter of a matplotlib Polygon.
Args:
polygon (matplotlib.patches.Polygon): The input polygon.
noise_generator (PerlinNoise): An initialized PerlinNoise object.
amplitude (float): The maximum displacement distance for the noise.
frequency (float): The frequency/scale of the noise. Higher values
create more jagged, detailed noise.
num_subdivisions (int): The number of new points to add per edge.
Returns:
np.ndarray: A new set of vertices for the noisy polygon.
"""
original_vertices = polygon.get_xy()
noisy_vertices = []
# Iterate through each edge of the polygon
for i in range(len(original_vertices)):
p1 = original_vertices[i]
p2 = original_vertices[(i + 1) % len(original_vertices)]
# Subdivide the edge into new points
for j in range(num_subdivisions):
# Linearly interpolate to get a new point on the edge
t = j / num_subdivisions
new_point = p1 + t * (p2 - p1)
# Calculate the direction perpendicular to the edge
# (dx, dy) -> (-dy, dx) is a simple perpendicular vector
edge_vector = p2 - p1
perp_vector = np.array([-edge_vector[1], edge_vector[0]])
# Normalize the perpendicular vector
perp_vector = perp_vector / np.linalg.norm(perp_vector) if np.linalg.norm(perp_vector) != 0 else np.array([0,0])
# Generate Perlin noise value for the new point's location
noise_val = noise_generator([new_point[0] * frequency, new_point[1] * frequency])
# Calculate the displacement vector
displacement = noise_val * amplitude * perp_vector
# Apply the displacement
noisy_point = new_point + displacement
noisy_vertices.append(noisy_point)
return np.array(noisy_vertices)
# 1. Define your initial list of polygons
polygon_list = patches
# 2. Initialize the Perlin Noise generator
# A seed ensures the noise is reproducible
noise = PerlinNoise(octaves=13, seed=1)
# 3. Apply the noise to each polygon and create new ones
noisy_polygon_list = []
for p in polygon_list:
new_vertices = add_perlin_noise_to_polygon(p, noise, amplitude=0.1, frequency=50, num_subdivisions=20)
noisy_polygon_list.append(Polygon(new_vertices, closed=True, facecolor='lightgreen', edgecolor='green', label="Noisy"))
# 4. Plot the original and noisy polygons for comparison
fig4, ax4 = plt.subplots(1)
# for p in polygon_list:
# ax4.add_patch(p)
for p in noisy_polygon_list:
ax4.add_patch(p)
ax4.set_title("Original vs. Perlin Noise Polygons")
# ax4.set_aspect('equal', adjustable='box')
# ax4.set_xlim(-0.2, 3.2)
# ax4.set_ylim(-0.2, 3.2)
# Create a simple legend
# ax.legend(handles=[
# plt.Line2D([0], [0], color='blue', linestyle='-'),
# plt.Line2D([0], [0], color='green', linestyle='-')
# ], labels=['Original', 'Noisy'])
ax4.autoscale_view()
fig4.set_size_inches(9.5, 5.5)
#ax.set_facecolor('xkcd:sea blue')
# plt.axis('off')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
from perlin_noise import PerlinNoise
def add_perlin_noise_to_polygon(polygon, noise_generator, amplitude=0.1, frequency=10, num_subdivisions=20):
"""
Applies Perlin noise to the perimeter of a matplotlib Polygon.
Args:
polygon (matplotlib.patches.Polygon): The input polygon.
noise_generator (PerlinNoise): An initialized PerlinNoise object.
amplitude (float): The maximum displacement distance for the noise.
frequency (float): The frequency/scale of the noise. Higher values
create more jagged, detailed noise.
num_subdivisions (int): The number of new points to add per edge.
Returns:
np.ndarray: A new set of vertices for the noisy polygon.
"""
original_vertices = polygon.get_xy()
noisy_vertices = []
# Iterate through each edge of the polygon
for i in range(len(original_vertices)):
p1 = original_vertices[i]
p2 = original_vertices[(i + 1) % len(original_vertices)]
# Subdivide the edge into new points
for j in range(num_subdivisions):
# Linearly interpolate to get a new point on the edge
t = j / num_subdivisions
new_point = p1 + t * (p2 - p1)
# Calculate the direction perpendicular to the edge
# (dx, dy) -> (-dy, dx) is a simple perpendicular vector
edge_vector = p2 - p1
perp_vector = np.array([-edge_vector[1], edge_vector[0]])
# Normalize the perpendicular vector
perp_vector = perp_vector / np.linalg.norm(perp_vector) if np.linalg.norm(perp_vector) != 0 else np.array([0,0])
# Generate Perlin noise value for the new point's location
noise_val = noise_generator([new_point[0] * frequency, new_point[1] * frequency])
# Calculate the displacement vector
displacement = noise_val * amplitude * perp_vector
# Apply the displacement
noisy_point = new_point + displacement
noisy_vertices.append(noisy_point)
return np.array(noisy_vertices)
# 1. Define your initial list of polygons
polygon_list = patches
# 2. Initialize the Perlin Noise generator
# A seed ensures the noise is reproducible
noise = PerlinNoise(octaves=13, seed=1)
# 3. Apply the noise to each polygon and create new ones
noisy_polygon_list = []
for p in polygon_list:
new_vertices = add_perlin_noise_to_polygon(p, noise, amplitude=0.1, frequency=50, num_subdivisions=20)
noisy_polygon_list.append(Polygon(new_vertices, closed=True, facecolor='lightgreen', edgecolor='green', label="Noisy"))
# 4. Plot the original and noisy polygons for comparison
fig4, ax4 = plt.subplots(1)
# for p in polygon_list:
# ax4.add_patch(p)
for p in noisy_polygon_list:
ax4.add_patch(p)
ax4.set_title("Original vs. Perlin Noise Polygons")
# ax4.set_aspect('equal', adjustable='box')
# ax4.set_xlim(-0.2, 3.2)
# ax4.set_ylim(-0.2, 3.2)
# Create a simple legend
# ax.legend(handles=[
# plt.Line2D([0], [0], color='blue', linestyle='-'),
# plt.Line2D([0], [0], color='green', linestyle='-')
# ], labels=['Original', 'Noisy'])
ax4.autoscale_view()
fig4.set_size_inches(9.5, 5.5)
#ax.set_facecolor('xkcd:sea blue')
# plt.axis('off')
plt.show()
Fazer um teste com shapely
In [19]:
Copied!
import matplotlib.pyplot as plt
import numpy as np
import shapely
from sklearn.datasets import make_blobs
from shapely.geometry import MultiPoint
# Generate 5 random clusters of points
# X, y = make_blobs(n_samples=500, n_features=2, centers=5, random_state=42)
# Create a plot
fig, ax = plt.subplots(figsize=(10, 8))
# Define colors for each cluster
colors = plt.cm.viridis(np.linspace(0, 1, 7))
# Iterate through each cluster to compute and plot the concave hull
for cluster_id in np.unique(y):
# Get points for the current cluster
cluster_points = X[y == cluster_id]
# Create a MultiPoint object from the cluster points
multipoint = MultiPoint(cluster_points)
# Compute the concave hull.
# The 'ratio' parameter controls the concavity. A smaller ratio
# creates a more detailed, "concave" shape.
hull = shapely.concave_hull(multipoint, ratio=0.3)
# # Plot the original points for the cluster
# ax.scatter(cluster_points[:, 0], cluster_points[:, 1], s=50, c=[colors[cluster_id]], label=f'Cluster {cluster_id}')
# Plot the perimeter of the concave hull
# We extract the x and y coordinates from the hull's exterior
if hull.geom_type == 'Polygon':
hull_x, hull_y = hull.exterior.xy
ax.plot(hull_x, hull_y, color=colors[cluster_id], linewidth=2)
else:
# This handles cases where the hull might be a MultiPolygon or LineString
for geom in hull.geoms:
if hasattr(geom, 'exterior'):
hull_x, hull_y = geom.exterior.xy
ax.plot(hull_x, hull_y, color=colors[cluster_id], linewidth=2)
# Add a title, labels, and a legend to the plot
ax.set_title('Concave Hull Perimeter for Each Cluster', fontsize=16)
# ax.set_xlabel('Feature 1')
# ax.set_ylabel('Feature 2')
ax.legend()
# ax.grid(True)
plt.tight_layout()
# Display the plot
plt.show()
# You can also save the plot to a file
# plt.savefig('concave_hull_clusters.png')
import matplotlib.pyplot as plt
import numpy as np
import shapely
from sklearn.datasets import make_blobs
from shapely.geometry import MultiPoint
# Generate 5 random clusters of points
# X, y = make_blobs(n_samples=500, n_features=2, centers=5, random_state=42)
# Create a plot
fig, ax = plt.subplots(figsize=(10, 8))
# Define colors for each cluster
colors = plt.cm.viridis(np.linspace(0, 1, 7))
# Iterate through each cluster to compute and plot the concave hull
for cluster_id in np.unique(y):
# Get points for the current cluster
cluster_points = X[y == cluster_id]
# Create a MultiPoint object from the cluster points
multipoint = MultiPoint(cluster_points)
# Compute the concave hull.
# The 'ratio' parameter controls the concavity. A smaller ratio
# creates a more detailed, "concave" shape.
hull = shapely.concave_hull(multipoint, ratio=0.3)
# # Plot the original points for the cluster
# ax.scatter(cluster_points[:, 0], cluster_points[:, 1], s=50, c=[colors[cluster_id]], label=f'Cluster {cluster_id}')
# Plot the perimeter of the concave hull
# We extract the x and y coordinates from the hull's exterior
if hull.geom_type == 'Polygon':
hull_x, hull_y = hull.exterior.xy
ax.plot(hull_x, hull_y, color=colors[cluster_id], linewidth=2)
else:
# This handles cases where the hull might be a MultiPolygon or LineString
for geom in hull.geoms:
if hasattr(geom, 'exterior'):
hull_x, hull_y = geom.exterior.xy
ax.plot(hull_x, hull_y, color=colors[cluster_id], linewidth=2)
# Add a title, labels, and a legend to the plot
ax.set_title('Concave Hull Perimeter for Each Cluster', fontsize=16)
# ax.set_xlabel('Feature 1')
# ax.set_ylabel('Feature 2')
ax.legend()
# ax.grid(True)
plt.tight_layout()
# Display the plot
plt.show()
# You can also save the plot to a file
# plt.savefig('concave_hull_clusters.png')
C:\Users\ulima\AppData\Local\Temp\ipykernel_41092\3050873662.py:48: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument. ax.legend()
In [21]:
Copied!
# Próximo passo adicionar Perlin Noise nesses polígonos e plotálos como patch ou como shapely mesmo.
# Próximo passo adicionar Perlin Noise nesses polígonos e plotálos como patch ou como shapely mesmo.