华数 代码

遍历寻找最大值并绘制径向柱形图

import pandas as pd
import os
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import seaborn as sns
import numpy as np
import tkinter as tk

# 文件夹路径,请根据实际情况调整
folder_path = r"C:\Users\HUAWEI\Desktop\2024年第五届“华数杯”全国大学生数学建模竞赛赛题\C题\附件"

best_score = 0  # 初始最高分
city_best_score_counts = {}  # 每个城市最高分景点数量的字典

# 遍历文件夹中的所有CSV文件
for file_name in os.listdir(folder_path):
    if file_name.endswith('.csv'):
        city_name = os.path.splitext(file_name)[0]  # 获取城市名(不包括扩展名)

        try:
            df = pd.read_csv(os.path.join(folder_path, file_name), usecols=[6])

            df.iloc[:, 0] = pd.to_numeric(df.iloc[:, 0], errors='coerce')
        except Exception as e:
            print(f"读取文件 {file_name} 时出错: {e}")
            continue

        df = df.dropna()

        if not df.empty:
            max_score = df.iloc[:, 0].max()

            if max_score > best_score:
                best_score = max_score

            best_score_count_city = df[df.iloc[:, 0] == best_score].shape[0]
            city_best_score_counts[city_name] = best_score_count_city

total_best_score_count = sum(city_best_score_counts.values())

top_cities = sorted(city_best_score_counts.items(), key=lambda x: x[1], reverse=True)[:10]

cities_list=[]
count_list=[]

print(f"全国最高分(Best Score): {best_score}")
print(f"全国获得最高分的景点总数: {total_best_score_count}")
print("前10个城市及其获得最高分景点的数量:")
for city, count in top_cities:
    cities_list.append(city)
    count_list.append(count)
    print(f"{city}: {count}个景点")

plt.rcParams['font.sans-serif'] = ['KaiTi']


plt.figure(figsize=(12, 12))
ax = plt.subplot(111, polar=True)
plt.title('城市BS景点数量条形图', fontsize=25,pad=30)
plt.axis()

# 忽略 Matplotlib 的弃用警告
Warning.filterwarnings("ignore", category=matplotlib.MatplotlibDeprecationWarning)
viridis_cmap = cm.get_cmap('viridis')
colors = [viridis_cmap(i) for i in np.linspace(0, 1, len(count_list))]

lowerLimit = 0
max_v = max(count_list)

heights = count_list
width = 2 * np.pi / len(count_list)

indexes = list(range(1, len(cities_list) + 1))
angles = [element * width for element in indexes]

bars = ax.bar(x=angles, height=heights, width=width, bottom=lowerLimit,
                  linewidth=1, edgecolor="white", color=colors)
labelPadding = 0.5

for bar, angle, height, label in zip(bars, angles, heights, cities_list):
        rotation = np.rad2deg(angle)
        alignment = ""
        # deal with alignment
        if angle >= np.pi / 2 and angle < 3 * np.pi / 2:
            alignment = "right"
            rotation = rotation + 180
        else:
            alignment = "left"
        ax.text(x=angle, y=lowerLimit + bar.get_height() + labelPadding,
                s=label, ha=alignment, va='center', rotation=rotation,
                rotation_mode="anchor")
        ax.set_thetagrids([], labels=[])
plt.savefig('问题一可视化.png', dpi=300)

利用熵权法加不同指标并找出评分前十的城市及圆形条形图,热力图及以地图为底的坐标散点图


import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from scipy.linalg import eig
import numpy as np
import warnings
import matplotlib.cm as cm
import cartopy.crs as ccrs
import cartopy.feature as cfeature

warnings.filterwarnings("ignore", category=RuntimeWarning)

# 设置全局字体为中文
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.rcParams['axes.unicode_minus'] = False

# 加载数据
file_path = 'Q2_Data.xlsx'
data = pd.read_excel(file_path)

# 显示数据结构,确保正确加载
print("数据预览:")
print(data.head())

# 提取需要的指标
features = [
    'AQI', '绿化覆盖率 (%)',
    '历史遗迹数量', '博物馆数量', '文化活动频次', '文化设施数量',
    '公共交通覆盖率 (%)', '线路密度 (km/km²)', '高速公路里程 (km)', '机场航班数量',
    '年平均气温 (℃)', '年降水量 (mm)', '适宜旅游天数', '空气湿度 (%)',
    '餐馆数量', '特色美食数量', '美食活动频次'
]


for feature in features:
    data[feature] = pd.to_numeric(data[feature], errors='coerce')

data.dropna(subset=features, inplace=True)

scaler = StandardScaler()
standardized_data = scaler.fit_transform(data[features])

standardized_data = pd.DataFrame(standardized_data, columns=features)
standardized_data['城市'] = data['来源城市']

AHP_matrix = np.array([
    [1, 1/3, 1/5, 1/2, 1/4],
    [3, 1, 1/3, 2, 1/2],
    [5, 3, 1, 4, 2],
    [2, 1/2, 1/4, 1, 1/3],
    [4, 2, 1/2, 3, 1]
])

eig_values, eig_vectors = eig(AHP_matrix)
max_eig_value = np.max(np.real(eig_values))
max_eig_vector = np.real(eig_vectors[:, np.argmax(np.real(eig_values))])

weights = max_eig_vector / np.sum(max_eig_vector)
print("权重向量:", weights)

categories = {
    '环境环保': ['AQI', '绿化覆盖率 (%)'],
    '人文底蕴': ['历史遗迹数量', '博物馆数量', '文化活动频次', '文化设施数量'],
    '交通便利': ['公共交通覆盖率 (%)', '线路密度 (km/km²)', '高速公路里程 (km)', '机场航班数量'],
    '气候': ['年平均气温 (℃)', '年降水量 (mm)', '适宜旅游天数', '空气湿度 (%)'],
    '美食': ['餐馆数量', '特色美食数量', '美食活动频次']
}

pca_data = pd.DataFrame()
pca = PCA(n_components=1)
for category, features in categories.items():
    pca_result = pca.fit_transform(standardized_data[features])
    pca_data[category] = pca_result.flatten()

# 添加城市列
pca_data['城市'] = data['来源城市']

# 基于熵权法的TOPSIS进行综合评价
def entropy_weight(data):
    k = 1.0 / np.log(len(data))
    data = data / (data.sum(axis=0) + 1e-10)  # 归一化并避免出现0值
    data = data * np.log(data + 1e-10)  # 避免取对数时出现无效值
    entropy = -k * (data.sum(axis=0))
    weight = (1 - entropy) / (1 - entropy).sum()
    return weight

# 计算权重
topsis_weights = entropy_weight(pca_data.drop(columns=['城市']))

# TOPSIS综合评价
def topsis(data, weight):
    data = data.values
    weight = np.array(weight)
    Z = data / np.sqrt((data**2).sum(axis=0))
    A_pos = Z.max(axis=0)
    A_neg = Z.min(axis=0)
    D_pos = np.sqrt(((Z - A_pos) ** 2 * weight).sum(axis=1))
    D_neg = np.sqrt(((Z - A_neg) ** 2 * weight).sum(axis=1))
    score = D_neg / (D_pos + D_neg)
    return score

topsis_scores = topsis(pca_data.drop(columns=['城市']), topsis_weights)
pca_data['综合评分'] = topsis_scores

top_50_cities = pca_data.sort_values(by='综合评分', ascending=False).head(50)

print("最令外国游客向往的50个城市:")
print(top_50_cities[['城市', '综合评分']])

top_50_cities = pca_data.sort_values(by='综合评分', ascending=False).head(50)
top_50_cities['城市'] = top_50_cities['城市'].replace('楚雄州', '广州')
print(list(top_50_cities['城市']))

plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.gcf().set_size_inches(20, 15)



max_val = max(top_50_cities['综合评分'])* 1.01
ax = plt.subplot(projection='polar')
plt.title('最令外国游客向往的 50 个城市', fontsize=25,pad=30)
ax.set_theta_zero_location('N')
ax.set_theta_direction(1)
ax.set_rlabel_position(0)
ax.set_thetagrids([], labels=[])
ax.set_rgrids(range(len(top_50_cities['城市'])), labels=top_50_cities['城市'])
ax.grid(False)

ax = plt.subplot(projection='polar')

viridis_r = cm.get_cmap('viridis_r')

colors = [viridis_r(i / (len(top_50_cities['综合评分']) - 1)) for i in range(len(top_50_cities['综合评分']))]

for i in range(len(top_50_cities['综合评分'])):
    ax.barh(i, list(top_50_cities['综合评分'])[i] * 2 * np.pi/max_val,
            label=list(top_50_cities['城市'])[i],color=colors[i])

ax.set_yticks(range(len(top_50_cities)))
ax.set_yticklabels(top_50_cities['城市'], fontsize=7)


plt.legend(bbox_to_anchor=(1.05, 1), loc=2,fontsize=13)
plt.savefig('50个城市条形图.png', dpi=300)

plt.figure(figsize=(14, 10))
heatmap_data = standardized_data.loc[top_50_cities.index, features]
plt.imshow(heatmap_data, aspect='auto', cmap='RdBu')
plt.colorbar(label='标准化得分')
plt.xticks(ticks=np.arange(len(features)), labels=features, rotation=90)
plt.yticks(ticks=np.arange(len(top_50_cities)), labels=top_50_cities['城市'])
plt.title('前50个城市在不同指标上的得分情况',fontsize=20,pad=30)
plt.savefig('50个城市得分情况热力图.png', dpi=300)

cities_coords = pd.read_csv(r"C:\Users\HUAWEI\Desktop\华数\问题2\城市经纬度_1.csv", encoding='GBK')
merged_data = pd.merge(top_50_cities, cities_coords, on='城市', how='left')

fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree())
ax.add_feature(cfeature.BORDERS.with_scale('50m'), linewidth=0.8)
ax.add_feature(cfeature.COASTLINE.with_scale('110m'), linewidth=0.8)
province_boundaries = cfeature.NaturalEarthFeature(
    category='cultural',
    name='admin_1_states_provinces_lines',
    scale='50m',
    facecolor='none',
    edgecolor='gray',
    linestyle=':'
)

ax.add_feature(province_boundaries)
scatter = ax.scatter(merged_data['经度'], merged_data['纬度'], c=merged_data['综合评分'], cmap='viridis_r', s=80, alpha=0.7,
                     transform=ccrs.PlateCarree())

plt.colorbar(scatter, ax=ax, label='综合评分')
for i, city in enumerate(merged_data['城市']):
    ax.text(merged_data['经度'].iloc[i], merged_data['纬度'].iloc[i], city, fontsize=7, ha='center', va='center',
            transform=ccrs.PlateCarree())

plt.xlabel('经度')
plt.ylabel('纬度')
plt.title('50个城市分布情况散点图', fontsize=15,pad=30)
plt.savefig('50个城市分布情况散点图.png', dpi=300)

提取评分前五十的城市

import pandas as pd
import numpy as np

df = pd.read_csv('Q3_top50.csv')
highest_rated = df[df.groupby('来源城市')['评分'].transform('max') == df['评分']]
random_selected = highest_rated.groupby('来源城市').apply(lambda x: x.sample(1)).reset_index(drop=True)
random_selected.to_csv('Q3_top50_topscore.csv', index=False)

对前50个城市的数据集进行预处理

import pandas as pd

# 定义前50个城市列表
top_50_cities = ['宜昌', '福州', '巴中', '百色', '白城', '保定', '赣州', '忻州', '珠海', '佳木斯', '烟台', '运城', '唐山', '汕尾', '榆林', '邵阳', '定西', '攀枝花', '儋州', '恩施', '潜江', '雄安新区', '杭州', '贺州', '扬州', '咸宁', '呼和浩特', '惠州', '济源', '嘉峪关', '朔州', '五家渠', '晋城', '南充', '可克达拉', '潍坊', '丽江', '通化', '临高', '台州', '泸州', '广州', '贵阳', '中山', '琼海', '成都', '北京', '安庆', '常德', '三亚']

# 加载数据,指定编码格式
file_path = 'Q3_all.xlsx'
data = pd.read_excel(file_path)


# 提取前50个城市的信息
filtered_data = data[data['来源城市'].isin(top_50_cities)]

# 删除“建议游玩时长”为空值的行
filtered_data = filtered_data.dropna(subset=['建议游玩时间'])

# 显示提取并删除后的信息
print("前50个城市的信息(删除“建议游玩时长”为空值的行):")
print(filtered_data.head())

# 保存提取并删除后的信息到新的CSV文件
filtered_data.to_csv('Q3_top50.csv', index=False)
print("提取并删除后的信息已保存到 'Q3_top50.csv'")

增加各个城市的经纬度信息

import pandas as pd

# 读取CSV文件
file_path = 'Q3_top50_topscore.csv'
data = pd.read_csv(file_path)

city_data = {
    '城市':  ['宜昌', '福州', '巴中', '百色', '白城', '保定', '赣州', '忻州', '珠海', '佳木斯', '烟台', '运城', '唐山', '汕尾', '榆林', '邵阳', '定西', '攀枝花', '儋州', '恩施', '潜江', '雄安新区', '杭州', '贺州', '扬州', '咸宁', '呼和浩特', '惠州', '济源', '嘉峪关', '朔州', '五家渠', '晋城', '南充', '可克达拉', '潍坊', '丽江', '通化', '临高', '台州', '泸州', '楚雄州', '贵阳', '中山', '琼海', '成都', '北京', '安庆', '常德', '三亚']
,
    '纬度': [

        29.56,
        26.0745,
        31.15,
        23.91,
        44.1357,
        38.1,
        24.29,
        38.605,
        21.48,
        37.33,
        34.35,
        38.55,
        22.37,
        36.57,
        19.9186,
        27.12,
        35.5807,
        26.5823,
        19.52,
        29.5,
        30,
        38.43,
        30.3,
        23.39,
        32.15,
        29.53,
        40.8426,
        22.24,
        35.08,
        39.8023,
        39.34,
        44.05,
        35.3,
        30.35,
        44.7034,
        35.34,
        26.86,
        40.52,
        19.34,
        28.6564,
        27.39,
        23.1291,
        26.11,
        22.11,
        18.585,
        30.05,
        39.542,
        30.31,
        29.02,
        18.0934,

    ],
    '经度': [

110.15,
119.2965,
107.45,
106.62,
121.38,
113.4,
113.54,
110.533,
111.03,
121.2,
110.15,
117.31,
114.54,
107.15,
109.6873,
111.27,
104.6266,
101.716,
108.56,
109.4048,
112.00 ,
115.38,
120.2,
111.05,
119.54,
114.17,
111.749,
113.51,
112.35,
98.2901,
112.37,
87.2,
112.5,
105.27,
80.372,
118.2,
100.25,
125.1,
109.3,
121.42076,
105.0841,
113.2644,
106.07,
113.09,
110.705,
102.54,
116.2329,
117.02,
111.41,
108.563,

    ]
}

city_df = pd.DataFrame(city_data)

merged_data = pd.merge(data, city_df, left_on='来源城市', right_on='城市', how='left')

merged_data.drop(columns=['城市'], inplace=True)

output_file_path = 'Q3_top50_topscore_1.csv'
merged_data.to_csv(output_file_path, index=False)


模型建构及其地图为底的坐标折线图

import pandas as pd
import numpy as np
from geopy.distance import geodesic
import matplotlib.pyplot as plt
import contextily as ctx

plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.rcParams['axes.unicode_minus'] = False

# 读取CSV文件
file_path = 'Q3_top50_topscore_1.csv'

try:
    data = pd.read_csv(file_path, encoding='utf-8')
except UnicodeDecodeError:
    data = pd.read_csv(file_path, encoding='GBK')

data.columns = ['名字', '开放时间', '评分', '建议游玩时间', '门票', '来源城市', '纬度', '经度']

print(data.head())

def calculate_distance(lat1, lon1, lat2, lon2):
    return geodesic((lat1, lon1), (lat2, lon2)).kilometers

train_speed_kmh = 300
cost_per_km = 0.555
daily_rest_hours = 10

starting_city = '广州'
time_limit_hours = 144
effective_hours = time_limit_hours - daily_rest_hours * 7
cities = data['来源城市'].tolist()
visited_cities = [starting_city]
remaining_cities = [city for city in cities if city != starting_city]
current_city = starting_city
total_time_spent = 0
total_cost = 0
stay_durations = [2.5]
total_costs_per_city = [138]

city_info = {
    row['来源城市']: {
        'coords': (row['纬度'], row['经度']),
        'score': row['评分'],
        'suggested_time': row['建议游玩时间'],
        'ticket_price': float(row['门票'])
    }
    for idx, row in data.iterrows()
}


while remaining_cities and total_time_spent < effective_hours:
    min_distance = float('inf')
    next_city = None

    for city in remaining_cities:
        distance = calculate_distance(
            city_info[current_city]['coords'][0], city_info[current_city]['coords'][1],
            city_info[city]['coords'][0], city_info[city]['coords'][1]
        )
        if distance < min_distance:
            min_distance = distance
            next_city = city

    if next_city:
        travel_time = min_distance / train_speed_kmh
        suggested_time = city_info[next_city]['suggested_time']
        if total_time_spent + travel_time + suggested_time > effective_hours:
            break
        total_time_spent += travel_time + suggested_time
        travel_cost = min_distance * cost_per_km
        attraction_cost = city_info[next_city]['ticket_price']
        total_city_cost = travel_cost + attraction_cost
        total_costs_per_city.append(total_city_cost)
        total_cost += total_city_cost
        visited_cities.append(next_city)
        stay_durations.append(suggested_time)
        remaining_cities.remove(next_city)
        current_city = next_city


total_scores = sum(city_info[city]['score'] for city in visited_cities)
result = {
    'Visited Cities': visited_cities,
    'Stay Durations': stay_durations,
    'Total Costs per City (RMB)': total_costs_per_city,
    'Total Time Spent (hours)': total_time_spent + daily_rest_hours * len(visited_cities),
    'Total Cost (RMB)': total_cost,
    'Total Cities Visited': len(visited_cities),
    'Total Scores': total_scores
}


result_df = pd.DataFrame([result])
print(sum(result['Stay Durations']))
print(sum(result['Total Costs per City (RMB)']))


latitudes = [city_info[city]['coords'][0] for city in visited_cities]
longitudes = [city_info[city]['coords'][1] for city in visited_cities]

fig, ax = plt.subplots(figsize=(10, 8))
plt.plot(longitudes, latitudes, marker='o', linestyle='-', color='black', markerfacecolor='red')
for i, city in enumerate(visited_cities):
    plt.text(longitudes[i], latitudes[i], city, fontsize=9)
ctx.add_basemap(ax, crs="EPSG:4326", source=ctx.providers.CartoDB.Positron)
plt.xlabel('经度')
plt.ylabel('纬度')
plt.title('旅游路线图', fontsize=25, pad=20)
plt.grid(True)
plt.savefig('旅游路线图.png', dpi=300)


scores = [city_info[city]['score'] for city in visited_cities]
def convert_to_10_scale(original_score):
    original_max_score = 5
    new_max_score = 10
    return (original_score / original_max_score) * new_max_score
converted_scores = [convert_to_10_scale(city_info[city]['score']) for city in visited_cities]

fig, ax1 = plt.subplots(figsize=(12, 8))
color_stay = 'skyblue'
color_score = 'yellow'
color_cost = 'red'
bar_width = 0.35


ax1.bar(visited_cities, stay_durations, color=color_stay, width=bar_width,alpha=0.3, label='停留时间 (小时)')

ax1.bar(visited_cities, converted_scores, color=color_score, width=bar_width, alpha=0.3, label='评分')

ax2 = ax1.twinx()
ax2.plot(visited_cities, total_costs_per_city, marker='o', linestyle='-', color=color_cost, label='城市总花费花费 (RMB)')

ax1.set_ylim(0, 15)
ax2.set_ylim(0, max(total_costs_per_city) + 10)
ax1.set_xlabel('城市')
ax1.set_ylabel('停留时间 (小时)、评分', color=color_stay)
ax2.set_ylabel('花费', color=color_score)
plt.title('城市停留时间、评分及总花费')

ax1.legend(loc='upper left')
ax2.legend(loc='upper right')
plt.xticks(rotation=45)
ax1.grid(True)
plt.savefig('问题三时间、花费、评分图.png', dpi=300)

对时间限制后的模型建构及其地图为底的坐标折线图

import pandas as pd
import numpy as np
from geopy.distance import geodesic
import matplotlib.pyplot as plt
import pandas as pd
from geopy.distance import geodesic
import matplotlib.pyplot as plt
import geopandas as gpd
from shapely.geometry import Point, LineString
import contextily as ctx

file_path = 'Q3_top50_topscore_1.csv'

try:
    data = pd.read_csv(file_path, encoding='utf-8')
except UnicodeDecodeError:
    data = pd.read_csv(file_path, encoding='GBK')

# 更改列名
data.columns = ['名字', '开放时间', '评分', '建议游玩时间', '门票', '来源城市', '纬度', '经度']
print(data.head())

def calculate_distance(lat1, lon1, lat2, lon2):
    return geodesic((lat1, lon1), (lat2, lon2)).kilometers

# 定义高铁速度和费用参数
train_speed_kmh = 300
cost_per_km = 0.555
daily_rest_hours = 10

# 初始化路径规划变量
starting_city = '广州'
time_limit_hours = 144
effective_hours = time_limit_hours - 7 * daily_rest_hours
cities = data['来源城市'].tolist()
visited_cities = [starting_city]
remaining_cities = [city for city in cities if city != starting_city]
current_city = starting_city
total_time_spent = 0
total_cost = 0
total_ticket_cost = 0
total_train_cost = 0
stay_durations = [2.5]
total_costs_per_city = [138]

city_info = {
    row['来源城市']: {'coords': (row['纬度'], row['经度']), 'score': row['评分'], 'suggested_time': row['建议游玩时间'], 'ticket_price': row['门票']}
    for idx, row in data.iterrows()
}

while remaining_cities and total_time_spent < effective_hours:
    min_cost = float('inf')
    next_city = None
    for city in remaining_cities:
        distance = calculate_distance(
            city_info[current_city]['coords'][0], city_info[current_city]['coords'][1],
            city_info[city]['coords'][0], city_info[city]['coords'][1]
        )
        travel_time = distance / train_speed_kmh
        travel_cost = distance * cost_per_km
        ticket_price = city_info[city]['ticket_price']
        total_cost_for_city = travel_cost + ticket_price
        if total_cost_for_city < min_cost:
            min_cost = total_cost_for_city
            next_city = city

    if next_city:
        distance = calculate_distance(
            city_info[current_city]['coords'][0], city_info[current_city]['coords'][1],
            city_info[next_city]['coords'][0], city_info[next_city]['coords'][1]
        )
        travel_time = distance / train_speed_kmh
        suggested_time = city_info[next_city]['suggested_time']
        if total_time_spent + travel_time + suggested_time > effective_hours:
            break
        total_time_spent += travel_time + suggested_time
        travel_cost = distance * cost_per_km
        ticket_price = city_info[next_city]['ticket_price']
        total_cost = travel_cost + ticket_price
        total_costs_per_city.append(total_cost)
        total_train_cost += travel_cost
        total_ticket_cost += ticket_price
        visited_cities.append(next_city)
        stay_durations.append(suggested_time)
        remaining_cities.remove(next_city)
        current_city = next_city

total_scores = sum(city_info[city]['score'] for city in visited_cities)
total_travel_time = total_time_spent + len(visited_cities) * daily_rest_hours

print(f"Visited Cities: {visited_cities}")
print(f"Stay Durations: {stay_durations}")
print(f"Total Time Spent (hours): {total_travel_time}")
print(f"Total Cost (RMB): {total_cost}")
print(f"Total Ticket Cost (RMB): {total_ticket_cost}")
print(f"Total Train Cost (RMB): {total_train_cost}")
print(f"Total Cities Visited: {len(visited_cities)}")
print(f"Total Scores: {total_scores}")

result = {
    'Visited Cities': visited_cities,
    'Stay Durations': stay_durations,
    'Total Time Spent (hours)': total_travel_time,
    'Total Cost (RMB)': total_cost,
    'Total Costs per City (RMB)': total_costs_per_city,
    'Total Ticket Cost (RMB)': total_ticket_cost,
    'Total Train Cost (RMB)': total_train_cost,
    'Total Cities Visited': len(visited_cities),
    'Total Scores': total_scores
}

result_df = pd.DataFrame([result])
print(result_df)
print(sum(result['Stay Durations']))
print(sum(result['Total Costs per City (RMB)']))

gdf = gpd.GeoDataFrame(
    visited_cities,
    geometry=[Point(city_info[city]['coords'][1], city_info[city]['coords'][0]) for city in visited_cities],
    columns=['City']
)
gdf.set_crs(epsg=4326, inplace=True)

route = LineString(gdf.geometry.tolist())

fig, ax = plt.subplots(1, 1, figsize=(10, 10))
gdf.plot(ax=ax, color='red', edgecolor='black', markersize=50)
gpd.GeoSeries(route).plot(ax=ax, color='black')
for x, y, label in zip(gdf.geometry.x, gdf.geometry.y, visited_cities):
    ax.text(x, y, label, fontsize=12)

ctx.add_basemap(ax, crs=gdf.crs.to_string(), source=ctx.providers.CartoDB.Positron)

plt.rcParams['font.sans-serif'] = ['KaiTi']
plt.rcParams['axes.unicode_minus'] = False  # 正确显示负号
plt.xlabel('经度')
plt.ylabel('纬度')
plt.title('旅游路线', fontsize=25,pad=30)
plt.savefig('问题四旅游路线.png', dpi=300)

# 定义转换评分的函数
scores = [city_info[city]['score'] for city in visited_cities]
def convert_to_10_scale(original_score):
    original_max_score = 5  # 假设原始评分的最大值为5
    new_max_score = 10  # 新评分的最大值为10
    return (original_score / original_max_score) * new_max_score
converted_scores = [convert_to_10_scale(city_info[city]['score']) for city in visited_cities]


fig, ax1 = plt.subplots(figsize=(12, 8))
color_stay = 'skyblue'
color_score = 'yellow'
color_cost = 'red'
bar_width = 0.35

# 绘制停留时间
ax1.bar(visited_cities, stay_durations, color=color_stay, width=bar_width, label='停留时间 (小时)')

# 绘制评分
ax1.bar(visited_cities, converted_scores, color=color_score, width=bar_width, alpha=0.5, label='评分')

# 绘制总花费折线图
ax2 = ax1.twinx()
ax2.plot(visited_cities, total_costs_per_city, marker='o', linestyle='-', color=color_cost, label='城市总花费 (RMB)')

# 设置y轴范围
ax1.set_ylim(0, 15)
ax2.set_ylim(0, max(total_costs_per_city) + 30)
# 设置标题和标签
ax1.set_xlabel('城市')
ax1.set_ylabel('停留时间 (小时)、评分', color=color_stay)
ax2.set_ylabel('花费', color=color_score)
plt.title('城市停留时间、评分及总花费')

# 设置图例
ax1.legend(loc='upper left')
ax2.legend(loc='upper right')

# 显示x轴标签并旋转
plt.xticks(rotation=45)

# 显示网格
ax1.grid(True)

# 显示图表
plt.savefig('问题四时间、花费、评分图.png', dpi=300)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值