用不同颜色绘制点

问题描述 投票:0回答:1

我正在尝试在具有给定半径周长的地图上可视化分支机构及其客户。我想保留分支点和客户点具有不同的颜色。我有一个分支的下拉菜单,因此在选择分支后,地图将居中并缩放到所选分支。然后我需要用不同的颜色来查看分支机构和客户。但到目前为止,我无法做到这一点。代码如下,任何帮助将不胜感激。

import plotly.express as px
import pandas as pd
import geopandas as gpd
from shapely.geometry import Polygon
from geopy.distance import geodesic

# Sample data
branches = pd.DataFrame({
    'name': ['Branch A', 'Branch B'],
    'lat': [39.647868, 41.06212],
    'lon': [27.882012, 28.98888]
})

customers = pd.DataFrame({
    'name': ['Customer 1', 'Customer 2', 'Customer 3'],
    'lat': [39.65113, 41.01879, 39.606046],
    'lon': [27.89559, 29.01249, 27.784534]
})

# Create a GeoDataFrame
branches_gdf = gpd.GeoDataFrame(branches, geometry=gpd.points_from_xy(branches.lon, branches.lat))
customers_gdf = gpd.GeoDataFrame(customers, geometry=gpd.points_from_xy(customers.lon, customers.lat))

# Function to create a circle
def create_circle(center, radius_km):
    angle_step = 10  # degrees
    angles = range(0, 360, angle_step)
    circle_points = [
        geodesic(kilometers=radius_km).destination((center.y, center.x), angle)
        for angle in angles
    ]
    return Polygon([(point.longitude, point.latitude) for point in circle_points])

# Define a perimeter in kilometers
perimeter_radius_km = 5

# Plot initial setup
fig = px.scatter_mapbox(
    lat=customers_gdf.geometry.y,
    lon=customers_gdf.geometry.x,
    hover_name=customers_gdf['name'],
    zoom=4,
    mapbox_style='carto-positron'
)

# Add all branch locations
fig.add_scattermapbox(
    lat=branches_gdf.geometry.y,
    lon=branches_gdf.geometry.x,
    mode='markers',
    marker=dict(size=12, color='red'),
    name='Branches',
    hovertext=branches_gdf['name']
)

# Add dropdown for selecting branches
buttons = []
for branch in branches_gdf.itertuples():
    branch_location = branch.geometry
    perimeter = create_circle(branch_location, perimeter_radius_km)
    customers_within = customers_gdf[customers_gdf.within(perimeter)]

    buttons.append(dict(
        args=[{
            'lat': [[branch_location.y] + customers_within.geometry.y.tolist(), [point[1] for point in perimeter.exterior.coords]],
            'lon': [[branch_location.x] + customers_within.geometry.x.tolist(), [point[0] for point in perimeter.exterior.coords]],
            'mode': ['markers', 'lines'],
            'marker': [dict(size=12, color='red')] + [dict(size=8, color='blue')] * len(customers_within) + [dict(size=0, color='blue')],
            'hovertext': [[branch.name] + customers_within['name'].tolist(), ['Perimeter']],
            'name': ['Branch and Customers', 'Perimeter']
        }],
        label=branch.name,
        method='update'
    ))
    buttons.append(dict(
        args=[{
            'lat': [customers_within.geometry.y.tolist() + [branch_location.y]],
            'lon': [customers_within.geometry.x.tolist() + [branch_location.x]],
            'marker': dict(size=8, color='blue'),  # Customer color
            'mapbox.center': {'lat': branch_location.y, 'lon': branch_location.x},
            'mapbox.zoom': 12
        }],
        label=branch.name,
        method='update'
    ))
    # Update the map center and zoom
    buttons[-1]['args'].append({'mapbox.center': {'lat': branch_location.y, 'lon': branch_location.x}, 'mapbox.zoom': 12})

fig.update_layout(
    updatemenus=[{
        'buttons': buttons,
        'direction': 'down',
        'showactive': True
    }]
)

# Save the interactive map to an HTML file
fig.write_html("interactive_map.html")
python plotly visualization
1个回答
0
投票

您可以使用此代码,我对其进行了一些细微的更改,因此它应该可以正常工作

import plotly.express as px
import pandas as pd
import geopandas as gpd
from shapely.geometry import Polygon
from geopy.distance import geodesic

# Sample data
branches = pd.DataFrame({
    'name': ['Branch A', 'Branch B'],
    'lat': [39.647868, 41.06212],
    'lon': [27.882012, 28.98888]
})

customers = pd.DataFrame({
    'name': ['Customer 1', 'Customer 2', 'Customer 3'],
    'lat': [39.65113, 41.01879, 39.606046],
    'lon': [27.89559, 29.01249, 27.784534]
})

# Create a GeoDataFrame
branches_gdf = gpd.GeoDataFrame(branches, geometry=gpd.points_from_xy(branches.lon, branches.lat))
customers_gdf = gpd.GeoDataFrame(customers, geometry=gpd.points_from_xy(customers.lon, customers.lat))

# Function to create a circle
def create_circle(center, radius_km):
    angle_step = 10  # degrees
    angles = range(0, 360, angle_step)
    circle_points = [
        geodesic(kilometers=radius_km).destination((center.y, center.x), angle)
        for angle in angles
    ]
    return Polygon([(point.longitude, point.latitude) for point in circle_points])

# Define a perimeter in kilometers
perimeter_radius_km = 5

# Plot initial setup
fig = px.scatter_mapbox(
    lat=customers_gdf.geometry.y,
    lon=customers_gdf.geometry.x,
    hover_name=customers_gdf['name'],
    zoom=4,
    mapbox_style='carto-positron'
)

# Add all branch locations
fig.add_scattermapbox(
    lat=branches_gdf.geometry.y,
    lon=branches_gdf.geometry.x,
    mode='markers',
    marker=dict(size=12, color='red'),
    name='Branches',
    hovertext=branches_gdf['name']
)

# Add dropdown for selecting branches
buttons = []
for branch in branches_gdf.itertuples():
    branch_location = branch.geometry
    perimeter = create_circle(branch_location, perimeter_radius_km)
    customers_within = customers_gdf[customers_gdf.within(perimeter)]

    buttons.append(dict(
        args=[{
            'lat': [customers_within.geometry.y.tolist() + [branch_location.y]],
            'lon': [customers_within.geometry.x.tolist() + [branch_location.x]],
            'marker': dict(size=8, color='blue'),  # Customer color
            'mapbox.center': {'lat': branch_location.y, 'lon': branch_location.x},
            'mapbox.zoom': 12
        }],
        label=branch.name,
        method='update'
    ))

fig.update_layout(
    updatemenus=[{
        'buttons': buttons,
        'direction': 'down',
        'showactive': True
    }]
)

# Save the interactive map to an HTML file
fig.write_html("interactive_map.html")
© www.soinside.com 2019 - 2024. All rights reserved.