Initial import: Music_Server, MusicFree, catalog-sync

This commit is contained in:
2026-05-23 16:51:14 +08:00
commit 069af30dba
847 changed files with 179878 additions and 0 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

@@ -0,0 +1,133 @@
'''
Function:
Implementation of MusicdlGUI
Author:
Zhenchao Jin
WeChat Official Account (微信公众号):
Charles的皮卡丘
'''
import os
import sys
import requests
from PyQt5 import *
from PyQt5 import QtCore
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from musicdl import musicdl
from PyQt5.QtWidgets import *
from musicdl.modules.utils.misc import touchdir, sanitize_filepath
'''MusicdlGUI'''
class MusicdlGUI(QWidget):
def __init__(self):
super(MusicdlGUI, self).__init__()
# initialize
self.setWindowTitle('MusicdlGUI —— Charles的皮卡丘')
self.setWindowIcon(QIcon(os.path.join(os.path.dirname(__file__), 'icon.ico')))
self.setFixedSize(900, 480)
self.initialize()
# search sources
self.src_names = ['QQMusicClient', 'KuwoMusicClient', 'MiguMusicClient', 'QianqianMusicClient', 'KugouMusicClient', 'NeteaseMusicClient']
self.label_src = QLabel('Search Engine:')
self.check_boxes = []
for src in self.src_names:
cb = QCheckBox(src, self)
cb.setCheckState(QtCore.Qt.Checked)
self.check_boxes.append(cb)
# input boxes
self.label_keyword = QLabel('Keywords:')
self.lineedit_keyword = QLineEdit('尾戒')
self.button_keyword = QPushButton('Search')
# search results table
self.results_table = QTableWidget()
self.results_table.setColumnCount(7)
self.results_table.setHorizontalHeaderLabels(['ID', 'Singers', 'Songname', 'Filesize', 'Duration', 'Album', 'Source'])
self.results_table.horizontalHeader().setStyleSheet("QHeaderView::section{background:skyblue;color:black;}")
self.results_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.results_table.setSelectionBehavior(QAbstractItemView.SelectRows)
# mouse click menu
self.context_menu = QMenu(self)
self.action_download = self.context_menu.addAction('Download')
# progress bar
self.bar_download = QProgressBar(self)
self.label_download = QLabel('Download progress:')
# grid
grid = QGridLayout()
grid.addWidget(self.label_src, 0, 0, 1, 1)
for idx, cb in enumerate(self.check_boxes): grid.addWidget(cb, 0, idx+1, 1, 1)
grid.addWidget(self.label_keyword, 1, 0, 1, 1)
grid.addWidget(self.lineedit_keyword, 1, 1, 1, len(self.src_names)-1)
grid.addWidget(self.button_keyword, 1, len(self.src_names), 1, 1)
grid.addWidget(self.label_download, 2, 0, 1, 1)
grid.addWidget(self.bar_download, 2, 1, 1, len(self.src_names))
grid.addWidget(self.results_table, 3, 0, len(self.src_names), len(self.src_names)+1)
self.grid = grid
self.setLayout(grid)
# connect
self.button_keyword.clicked.connect(self.search)
self.results_table.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.results_table.customContextMenuRequested.connect(self.mouseclick)
self.action_download.triggered.connect(self.download)
'''initialize'''
def initialize(self):
self.search_results = {}
self.music_records = {}
self.selected_music_idx = -10000
self.music_client = None
'''mouseclick'''
def mouseclick(self):
self.context_menu.move(QCursor().pos())
self.context_menu.show()
'''download'''
def download(self):
self.selected_music_idx = str(self.results_table.selectedItems()[0].row())
song_info = self.music_records.get(self.selected_music_idx)
with requests.get(song_info['download_url'], headers=self.music_client.music_clients[song_info['source']].default_download_headers, stream=True, verify=False) as resp:
if resp.status_code == 200:
total_size, chunk_size, download_size = int(resp.headers['content-length']), 1024, 0
touchdir(song_info['work_dir'])
download_music_file_path = sanitize_filepath(os.path.join(song_info['work_dir'], song_info['song_name']+'.'+song_info['ext']))
with open(download_music_file_path, 'wb') as fp:
for chunk in resp.iter_content(chunk_size=chunk_size):
if not chunk: continue
fp.write(chunk)
download_size += len(chunk)
self.bar_download.setValue(int(download_size / total_size * 100))
QMessageBox().information(self, 'Successful Downloads', f"Finish downloading {song_info['song_name']} by {song_info['singers']}, see {download_music_file_path}")
self.bar_download.setValue(0)
'''search'''
def search(self):
self.initialize()
# selected music sources
music_sources = []
for cb in self.check_boxes:
if cb.isChecked():
music_sources.append(cb.text())
# keyword
keyword = self.lineedit_keyword.text()
# search
self.music_client = musicdl.MusicClient(music_sources=music_sources)
self.search_results = self.music_client.search(keyword=keyword)
# showing
count, row = 0, 0
for per_source_search_results in self.search_results.values():
count += len(per_source_search_results)
self.results_table.setRowCount(count)
for _, (_, per_source_search_results) in enumerate(self.search_results.items()):
for _, per_source_search_result in enumerate(per_source_search_results):
for column, item in enumerate([str(row), per_source_search_result['singers'], per_source_search_result['song_name'], per_source_search_result['file_size'], per_source_search_result['duration'], per_source_search_result['album'], per_source_search_result['source']]):
self.results_table.setItem(row, column, QTableWidgetItem(item))
self.results_table.item(row, column).setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
self.music_records.update({str(row): per_source_search_result})
row += 1
# return
return self.search_results
'''tests'''
if __name__ == '__main__':
app = QApplication(sys.argv)
gui = MusicdlGUI()
gui.show()
sys.exit(app.exec_())
@@ -0,0 +1,3 @@
requests
PyQt5
musicdl
Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

@@ -0,0 +1,5 @@
requests
musicdl
simpleaudio
pyaudio
pydub
@@ -0,0 +1,53 @@
'''
Function:
Implementation of SearchLyrics
Author:
Zhenchao Jin
WeChat Official Account (微信公众号):
Charles的皮卡丘
'''
import re
import os
from pydub import AudioSegment
from pydub.playback import play
from musicdl.modules.sources import NeteaseMusicClient
from musicdl.modules.utils.misc import sanitize_filepath
'''SearchLyrics'''
class SearchLyrics():
def __init__(self):
self.music_client = NeteaseMusicClient(search_size_per_source=1)
'''start'''
def start(self):
# inputs
keyword = input('Input lyrics: ')
# search and download music files
print('[INFO]: Searching and downloading music files by lyrics')
song_infos = self.music_client.search(keyword)[:1]
self.music_client.download(song_infos)
# extract audio clips
print('[INFO]: Extract the corresponding audio clip and play')
lyrics: str = song_infos[0]['lyric']
start, end = None, None
for lyric in lyrics.split('\n'):
if start is not None and end is not None:
break
if keyword in lyric:
start: str = re.findall(r'\[(.*?)\]', lyric)[0]
start = int(float(start.split(':')[0])) * 1000 * 60 + int(float(start.split(':')[1])) * 1000 - 1000
elif start is not None:
end: str = re.findall(r'\[(.*?)\]', lyric)[0]
end = int(float(end.split(':')[0])) * 1000 * 60 + int(float(end.split(':')[1])) * 1000 + 1000
# play
file_path = os.path.join(song_infos[0]['work_dir'], f"{song_infos[0]['song_name']}.{song_infos[0]['ext']}")
music = AudioSegment.from_mp3(file=sanitize_filepath(file_path))
music_cut = music[start: end]
music_cut.export(out_f=os.path.join(song_infos[0]['work_dir'], f"{song_infos[0]['song_name']}_cut.{song_infos[0]['ext']}"), format='mp3')
play(music_cut)
'''tests'''
if __name__ == '__main__':
client = SearchLyrics()
client.start()
@@ -0,0 +1,7 @@
jieba
numpy
pillow
musicdl==2.3.6
snownlp
wordcloud
pyecharts
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

@@ -0,0 +1,118 @@
'''
Function:
Implementation of SingerLyricsAnalysis
Author:
Zhenchao Jin
WeChat Official Account (微信公众号):
Charles的皮卡丘
'''
import os
import jieba
import pickle
import numpy as np
from PIL import Image
from snownlp import SnowNLP
from wordcloud import WordCloud
from musicdl.modules.sources import MiguMusicClient
'''SingerLyricsAnalysis'''
class SingerLyricsAnalysis():
def __init__(self):
self.root_dir = os.path.split(os.path.abspath(__file__))[0]
self.music_client = MiguMusicClient(search_size_per_source=2000)
'''start'''
def start(self):
while True:
singer_name = input('Input singer to analyze: ')
print(f'[INFO]: Searching {singer_name}')
infos = self.crawler(singer_name)
print(f'[INFO]: Analyzing {singer_name}')
self.analysis(infos)
'''crawler'''
def crawler(self, singer_name):
song_infos = self.music_client.search(keyword=singer_name)
self.save(singer_name=singer_name, song_infos=song_infos)
return song_infos
'''analysis'''
def analysis(self, song_infos):
# data clean
lyrics = []
for song_info in song_infos:
lyric = song_info['lyric']
lyric = lyric.split('\r\n')
lyric_filtered = []
for sentence in lyric:
sentence = sentence[10:]
if (not sentence) or ('' in sentence) or (self.root_dir in sentence) or ('[' in sentence) or (']' in sentence) or ('歌曲' in sentence): continue
lyric_filtered.append(sentence)
lyrics += lyric_filtered
# generatewordcloud
words_dict = {}
for sentence in lyrics:
words = jieba.cut(sentence)
for word in words:
word = word.strip()
if not word: continue
if len(word) < 2: continue
if word in words_dict: words_dict[word] += 1
else: words_dict[word] = 1
words_freq_sorted = sorted(words_dict.items(), key=lambda item: item[1])
words_freq_top10 = words_freq_sorted[-10:]
self.generatewordcloud(words_dict)
self.drawbar('%s歌曲中的词语TOP10' % self.root_dir, words_freq_top10)
# nlp analysis
nlp_dict = {'内容极度负面': 0, '内容较为负面': 0, '内容中性': 0, '内容较为正面': 0, '内容非常正面': 0}
for sentence in lyrics:
score = SnowNLP(sentence).sentiments
if score < 0.2:
nlp_dict['内容极度负面'] += 1
elif score >= 0.2 and score < 0.4:
nlp_dict['内容较为负面'] += 1
elif score >= 0.4 and score < 0.6:
nlp_dict['内容中性'] += 1
elif score >= 0.6 and score < 0.8:
nlp_dict['内容较为正面'] += 1
else:
nlp_dict['内容非常正面'] += 1
self.drawpie('%s的歌词情感分析' % self.root_dir, nlp_dict)
'''drawbar'''
def drawbar(self, title, infos):
from pyecharts.charts import Bar
from pyecharts import options as opts
from pyecharts.globals import ThemeType
bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))
bar.add_xaxis([item[0] for item in infos])
bar.add_yaxis('freq', [item[1] for item in infos])
bar.set_global_opts(title_opts=opts.TitleOpts(title=title))
bar.render(os.path.join(self.root_dir, title+'.html'))
'''drawpie'''
def drawpie(self, title, infos):
from pyecharts.charts import Pie
from pyecharts import options as opts
pie = Pie(init_opts=dict(theme='westeros', page_title=title)).add(title, data_pair=tuple(zip(infos.keys(), infos.values())), rosetype='area')
pie.set_global_opts(title_opts=opts.TitleOpts(title=title))
pie.render(os.path.join(self.root_dir, '%s.html' % title))
'''generatewordcloud'''
def generatewordcloud(self, infos):
mask = Image.open(os.path.join(self.root_dir, 'resources/mask.jpg'))
mask = np.array(mask)
wc = WordCloud(background_color='white', font_path=os.path.join(self.root_dir, 'resources/font_cn.TTF'), mask=mask)
result = wc.generate_from_frequencies(infos)
result.to_file(os.path.join(self.root_dir, 'wordcloud.png'))
'''save'''
def save(self, song_infos, singer_name):
data_save_path = os.path.join(self.root_dir, f'song_infos_{singer_name}.pkl')
with open(data_save_path, 'wb') as fp:
pickle.dump(song_infos, fp)
'''load'''
def load(self, singer_name):
data_save_path = os.path.join(self.root_dir, f'song_infos_{singer_name}.pkl')
fp = open(data_save_path, 'rb')
return pickle.load(fp)
'''tests'''
if __name__ == '__main__':
client = SingerLyricsAnalysis()
client.start()
Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

@@ -0,0 +1,159 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Awesome-pyecharts</title>
<script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
</head>
<body>
<div id="e7c5b8339a7c42849b00404c8a8ed598" class="chart-container" style="width:900px; height:500px;"></div>
<script>
var chart_e7c5b8339a7c42849b00404c8a8ed598 = echarts.init(
document.getElementById('e7c5b8339a7c42849b00404c8a8ed598'), 'light', {renderer: 'canvas'});
var option_e7c5b8339a7c42849b00404c8a8ed598 = {
"animation": true,
"animationThreshold": 2000,
"animationDuration": 1000,
"animationEasing": "cubicOut",
"animationDelay": 0,
"animationDurationUpdate": 300,
"animationEasingUpdate": "cubicOut",
"animationDelayUpdate": 0,
"series": [
{
"type": "bar",
"name": "freq",
"legendHoverLink": true,
"data": [
112,
116,
136,
138,
145,
162,
193,
196,
230,
250
],
"showBackground": false,
"barMinHeight": 0,
"barCategoryGap": "20%",
"barGap": "30%",
"large": false,
"largeThreshold": 400,
"seriesLayoutBy": "column",
"datasetIndex": 0,
"clip": true,
"zlevel": 0,
"z": 2,
"label": {
"show": true,
"position": "top",
"margin": 8
}
}
],
"legend": [
{
"data": [
"freq"
],
"selected": {
"freq": true
},
"show": true,
"padding": 5,
"itemGap": 10,
"itemWidth": 25,
"itemHeight": 14
}
],
"tooltip": {
"show": true,
"trigger": "item",
"triggerOn": "mousemove|click",
"axisPointer": {
"type": "line"
},
"showContent": true,
"alwaysShowContent": false,
"showDelay": 0,
"hideDelay": 100,
"textStyle": {
"fontSize": 14
},
"borderWidth": 0,
"padding": 5
},
"xAxis": [
{
"show": true,
"scale": false,
"nameLocation": "end",
"nameGap": 15,
"gridIndex": 0,
"inverse": false,
"offset": 0,
"splitNumber": 5,
"minInterval": 0,
"splitLine": {
"show": false,
"lineStyle": {
"show": true,
"width": 1,
"opacity": 1,
"curveness": 0,
"type": "solid"
}
},
"data": [
"\u4e0d\u8981",
"\u7231\u60c5",
"\u56de\u5fc6",
"\u4e00\u4e2a",
"\u77e5\u9053",
"\u79bb\u5f00",
"\u4ec0\u4e48",
"\u600e\u4e48",
"\u6ca1\u6709",
"\u6211\u4eec"
]
}
],
"yAxis": [
{
"show": true,
"scale": false,
"nameLocation": "end",
"nameGap": 15,
"gridIndex": 0,
"inverse": false,
"offset": 0,
"splitNumber": 5,
"minInterval": 0,
"splitLine": {
"show": false,
"lineStyle": {
"show": true,
"width": 1,
"opacity": 1,
"curveness": 0,
"type": "solid"
}
}
}
],
"title": [
{
"text": "\u5468\u6770\u4f26\u6b4c\u66f2\u4e2d\u7684\u8bcd\u8bedTOP10",
"padding": 5,
"itemGap": 10
}
]
};
chart_e7c5b8339a7c42849b00404c8a8ed598.setOption(option_e7c5b8339a7c42849b00404c8a8ed598);
</script>
</body>
</html>
@@ -0,0 +1,112 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>周杰伦的歌词情感分析</title>
<script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
<script type="text/javascript" src="https://assets.pyecharts.org/assets/themes/westeros.js"></script>
</head>
<body>
<div id="4ba593a441c441c4a398eae018a3d534" class="chart-container" style="width:900px; height:500px;"></div>
<script>
var chart_4ba593a441c441c4a398eae018a3d534 = echarts.init(
document.getElementById('4ba593a441c441c4a398eae018a3d534'), 'westeros', {renderer: 'canvas'});
var option_4ba593a441c441c4a398eae018a3d534 = {
"animation": true,
"animationThreshold": 2000,
"animationDuration": 1000,
"animationEasing": "cubicOut",
"animationDelay": 0,
"animationDurationUpdate": 300,
"animationEasingUpdate": "cubicOut",
"animationDelayUpdate": 0,
"series": [
{
"type": "pie",
"name": "\u5468\u6770\u4f26\u7684\u6b4c\u8bcd\u60c5\u611f\u5206\u6790",
"clockwise": true,
"data": [
{
"name": "\u5185\u5bb9\u6781\u5ea6\u8d1f\u9762",
"value": 1232
},
{
"name": "\u5185\u5bb9\u8f83\u4e3a\u8d1f\u9762",
"value": 2028
},
{
"name": "\u5185\u5bb9\u4e2d\u6027",
"value": 3097
},
{
"name": "\u5185\u5bb9\u8f83\u4e3a\u6b63\u9762",
"value": 2928
},
{
"name": "\u5185\u5bb9\u975e\u5e38\u6b63\u9762",
"value": 5213
}
],
"radius": [
"0%",
"75%"
],
"center": [
"50%",
"50%"
],
"roseType": "area",
"label": {
"show": true,
"position": "top",
"margin": 8
}
}
],
"legend": [
{
"data": [
"\u5185\u5bb9\u6781\u5ea6\u8d1f\u9762",
"\u5185\u5bb9\u8f83\u4e3a\u8d1f\u9762",
"\u5185\u5bb9\u4e2d\u6027",
"\u5185\u5bb9\u8f83\u4e3a\u6b63\u9762",
"\u5185\u5bb9\u975e\u5e38\u6b63\u9762"
],
"selected": {},
"show": true,
"padding": 5,
"itemGap": 10,
"itemWidth": 25,
"itemHeight": 14
}
],
"tooltip": {
"show": true,
"trigger": "item",
"triggerOn": "mousemove|click",
"axisPointer": {
"type": "line"
},
"showContent": true,
"alwaysShowContent": false,
"showDelay": 0,
"hideDelay": 100,
"textStyle": {
"fontSize": 14
},
"borderWidth": 0,
"padding": 5
},
"title": [
{
"text": "\u5468\u6770\u4f26\u7684\u6b4c\u8bcd\u60c5\u611f\u5206\u6790",
"padding": 5,
"itemGap": 10
}
]
};
chart_4ba593a441c441c4a398eae018a3d534.setOption(option_4ba593a441c441c4a398eae018a3d534);
</script>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

@@ -0,0 +1,159 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Awesome-pyecharts</title>
<script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
</head>
<body>
<div id="c9e5146742d24d4aaa84f446079d82ff" class="chart-container" style="width:900px; height:500px;"></div>
<script>
var chart_c9e5146742d24d4aaa84f446079d82ff = echarts.init(
document.getElementById('c9e5146742d24d4aaa84f446079d82ff'), 'light', {renderer: 'canvas'});
var option_c9e5146742d24d4aaa84f446079d82ff = {
"animation": true,
"animationThreshold": 2000,
"animationDuration": 1000,
"animationEasing": "cubicOut",
"animationDelay": 0,
"animationDurationUpdate": 300,
"animationEasingUpdate": "cubicOut",
"animationDelayUpdate": 0,
"series": [
{
"type": "bar",
"name": "freq",
"legendHoverLink": true,
"data": [
17,
17,
19,
20,
22,
26,
26,
27,
30,
41
],
"showBackground": false,
"barMinHeight": 0,
"barCategoryGap": "20%",
"barGap": "30%",
"large": false,
"largeThreshold": 400,
"seriesLayoutBy": "column",
"datasetIndex": 0,
"clip": true,
"zlevel": 0,
"z": 2,
"label": {
"show": true,
"position": "top",
"margin": 8
}
}
],
"legend": [
{
"data": [
"freq"
],
"selected": {
"freq": true
},
"show": true,
"padding": 5,
"itemGap": 10,
"itemWidth": 25,
"itemHeight": 14
}
],
"tooltip": {
"show": true,
"trigger": "item",
"triggerOn": "mousemove|click",
"axisPointer": {
"type": "line"
},
"showContent": true,
"alwaysShowContent": false,
"showDelay": 0,
"hideDelay": 100,
"textStyle": {
"fontSize": 14
},
"borderWidth": 0,
"padding": 5
},
"xAxis": [
{
"show": true,
"scale": false,
"nameLocation": "end",
"nameGap": 15,
"gridIndex": 0,
"inverse": false,
"offset": 0,
"splitNumber": 5,
"minInterval": 0,
"splitLine": {
"show": false,
"lineStyle": {
"show": true,
"width": 1,
"opacity": 1,
"curveness": 0,
"type": "solid"
}
},
"data": [
"\u554a\u554a\u554a",
"\u65f6\u5019",
"\u518d\u89c1",
"\u5411\u7740",
"\u592a\u9633",
"\u5c31\u662f",
"\u56e0\u4e3a",
"\u4e00\u4e2a",
"\u81ea\u5df1",
"\u6211\u4eec"
]
}
],
"yAxis": [
{
"show": true,
"scale": false,
"nameLocation": "end",
"nameGap": 15,
"gridIndex": 0,
"inverse": false,
"offset": 0,
"splitNumber": 5,
"minInterval": 0,
"splitLine": {
"show": false,
"lineStyle": {
"show": true,
"width": 1,
"opacity": 1,
"curveness": 0,
"type": "solid"
}
}
}
],
"title": [
{
"text": "\u6bdb\u963f\u654f\u6b4c\u66f2\u4e2d\u7684\u8bcd\u8bedTOP10",
"padding": 5,
"itemGap": 10
}
]
};
chart_c9e5146742d24d4aaa84f446079d82ff.setOption(option_c9e5146742d24d4aaa84f446079d82ff);
</script>
</body>
</html>
@@ -0,0 +1,112 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>毛阿敏的歌词情感分析</title>
<script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
<script type="text/javascript" src="https://assets.pyecharts.org/assets/themes/westeros.js"></script>
</head>
<body>
<div id="7f8115fd24c442ada43c45d8b3db3ca2" class="chart-container" style="width:900px; height:500px;"></div>
<script>
var chart_7f8115fd24c442ada43c45d8b3db3ca2 = echarts.init(
document.getElementById('7f8115fd24c442ada43c45d8b3db3ca2'), 'westeros', {renderer: 'canvas'});
var option_7f8115fd24c442ada43c45d8b3db3ca2 = {
"animation": true,
"animationThreshold": 2000,
"animationDuration": 1000,
"animationEasing": "cubicOut",
"animationDelay": 0,
"animationDurationUpdate": 300,
"animationEasingUpdate": "cubicOut",
"animationDelayUpdate": 0,
"series": [
{
"type": "pie",
"name": "\u6bdb\u963f\u654f\u7684\u6b4c\u8bcd\u60c5\u611f\u5206\u6790",
"clockwise": true,
"data": [
{
"name": "\u5185\u5bb9\u6781\u5ea6\u8d1f\u9762",
"value": 75
},
{
"name": "\u5185\u5bb9\u8f83\u4e3a\u8d1f\u9762",
"value": 147
},
{
"name": "\u5185\u5bb9\u4e2d\u6027",
"value": 269
},
{
"name": "\u5185\u5bb9\u8f83\u4e3a\u6b63\u9762",
"value": 296
},
{
"name": "\u5185\u5bb9\u975e\u5e38\u6b63\u9762",
"value": 577
}
],
"radius": [
"0%",
"75%"
],
"center": [
"50%",
"50%"
],
"roseType": "area",
"label": {
"show": true,
"position": "top",
"margin": 8
}
}
],
"legend": [
{
"data": [
"\u5185\u5bb9\u6781\u5ea6\u8d1f\u9762",
"\u5185\u5bb9\u8f83\u4e3a\u8d1f\u9762",
"\u5185\u5bb9\u4e2d\u6027",
"\u5185\u5bb9\u8f83\u4e3a\u6b63\u9762",
"\u5185\u5bb9\u975e\u5e38\u6b63\u9762"
],
"selected": {},
"show": true,
"padding": 5,
"itemGap": 10,
"itemWidth": 25,
"itemHeight": 14
}
],
"tooltip": {
"show": true,
"trigger": "item",
"triggerOn": "mousemove|click",
"axisPointer": {
"type": "line"
},
"showContent": true,
"alwaysShowContent": false,
"showDelay": 0,
"hideDelay": 100,
"textStyle": {
"fontSize": 14
},
"borderWidth": 0,
"padding": 5
},
"title": [
{
"text": "\u6bdb\u963f\u654f\u7684\u6b4c\u8bcd\u60c5\u611f\u5206\u6790",
"padding": 5,
"itemGap": 10
}
]
};
chart_7f8115fd24c442ada43c45d8b3db3ca2.setOption(option_7f8115fd24c442ada43c45d8b3db3ca2);
</script>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

@@ -0,0 +1,159 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Awesome-pyecharts</title>
<script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
</head>
<body>
<div id="0e6cd7fe63b54b57a9ec0a13dd21356d" class="chart-container" style="width:900px; height:500px;"></div>
<script>
var chart_0e6cd7fe63b54b57a9ec0a13dd21356d = echarts.init(
document.getElementById('0e6cd7fe63b54b57a9ec0a13dd21356d'), 'light', {renderer: 'canvas'});
var option_0e6cd7fe63b54b57a9ec0a13dd21356d = {
"animation": true,
"animationThreshold": 2000,
"animationDuration": 1000,
"animationEasing": "cubicOut",
"animationDelay": 0,
"animationDurationUpdate": 300,
"animationEasingUpdate": "cubicOut",
"animationDelayUpdate": 0,
"series": [
{
"type": "bar",
"name": "freq",
"legendHoverLink": true,
"data": [
55,
56,
57,
70,
71,
77,
80,
109,
114,
148
],
"showBackground": false,
"barMinHeight": 0,
"barCategoryGap": "20%",
"barGap": "30%",
"large": false,
"largeThreshold": 400,
"seriesLayoutBy": "column",
"datasetIndex": 0,
"clip": true,
"zlevel": 0,
"z": 2,
"label": {
"show": true,
"position": "top",
"margin": 8
}
}
],
"legend": [
{
"data": [
"freq"
],
"selected": {
"freq": true
},
"show": true,
"padding": 5,
"itemGap": 10,
"itemWidth": 25,
"itemHeight": 14
}
],
"tooltip": {
"show": true,
"trigger": "item",
"triggerOn": "mousemove|click",
"axisPointer": {
"type": "line"
},
"showContent": true,
"alwaysShowContent": false,
"showDelay": 0,
"hideDelay": 100,
"textStyle": {
"fontSize": 14
},
"borderWidth": 0,
"padding": 5
},
"xAxis": [
{
"show": true,
"scale": false,
"nameLocation": "end",
"nameGap": 15,
"gridIndex": 0,
"inverse": false,
"offset": 0,
"splitNumber": 5,
"minInterval": 0,
"splitLine": {
"show": false,
"lineStyle": {
"show": true,
"width": 1,
"opacity": 1,
"curveness": 0,
"type": "solid"
}
},
"data": [
"\u56de\u5fc6",
"\u7231\u60c5",
"\u662f\u5426",
"\u90a3\u4e48",
"\u81ea\u5df1",
"\u5982\u679c",
"\u4e00\u4e2a",
"\u4ec0\u4e48",
"\u6ca1\u6709",
"\u6211\u4eec"
]
}
],
"yAxis": [
{
"show": true,
"scale": false,
"nameLocation": "end",
"nameGap": 15,
"gridIndex": 0,
"inverse": false,
"offset": 0,
"splitNumber": 5,
"minInterval": 0,
"splitLine": {
"show": false,
"lineStyle": {
"show": true,
"width": 1,
"opacity": 1,
"curveness": 0,
"type": "solid"
}
}
}
],
"title": [
{
"text": "\u8bb8\u5d69\u6b4c\u66f2\u4e2d\u7684\u8bcd\u8bedTOP10",
"padding": 5,
"itemGap": 10
}
]
};
chart_0e6cd7fe63b54b57a9ec0a13dd21356d.setOption(option_0e6cd7fe63b54b57a9ec0a13dd21356d);
</script>
</body>
</html>
@@ -0,0 +1,112 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>许嵩的歌词情感分析</title>
<script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>
<script type="text/javascript" src="https://assets.pyecharts.org/assets/themes/westeros.js"></script>
</head>
<body>
<div id="7b066e6726024f9083cb49d258892ad7" class="chart-container" style="width:900px; height:500px;"></div>
<script>
var chart_7b066e6726024f9083cb49d258892ad7 = echarts.init(
document.getElementById('7b066e6726024f9083cb49d258892ad7'), 'westeros', {renderer: 'canvas'});
var option_7b066e6726024f9083cb49d258892ad7 = {
"animation": true,
"animationThreshold": 2000,
"animationDuration": 1000,
"animationEasing": "cubicOut",
"animationDelay": 0,
"animationDurationUpdate": 300,
"animationEasingUpdate": "cubicOut",
"animationDelayUpdate": 0,
"series": [
{
"type": "pie",
"name": "\u8bb8\u5d69\u7684\u6b4c\u8bcd\u60c5\u611f\u5206\u6790",
"clockwise": true,
"data": [
{
"name": "\u5185\u5bb9\u6781\u5ea6\u8d1f\u9762",
"value": 476
},
{
"name": "\u5185\u5bb9\u8f83\u4e3a\u8d1f\u9762",
"value": 865
},
{
"name": "\u5185\u5bb9\u4e2d\u6027",
"value": 1406
},
{
"name": "\u5185\u5bb9\u8f83\u4e3a\u6b63\u9762",
"value": 1424
},
{
"name": "\u5185\u5bb9\u975e\u5e38\u6b63\u9762",
"value": 2636
}
],
"radius": [
"0%",
"75%"
],
"center": [
"50%",
"50%"
],
"roseType": "area",
"label": {
"show": true,
"position": "top",
"margin": 8
}
}
],
"legend": [
{
"data": [
"\u5185\u5bb9\u6781\u5ea6\u8d1f\u9762",
"\u5185\u5bb9\u8f83\u4e3a\u8d1f\u9762",
"\u5185\u5bb9\u4e2d\u6027",
"\u5185\u5bb9\u8f83\u4e3a\u6b63\u9762",
"\u5185\u5bb9\u975e\u5e38\u6b63\u9762"
],
"selected": {},
"show": true,
"padding": 5,
"itemGap": 10,
"itemWidth": 25,
"itemHeight": 14
}
],
"tooltip": {
"show": true,
"trigger": "item",
"triggerOn": "mousemove|click",
"axisPointer": {
"type": "line"
},
"showContent": true,
"alwaysShowContent": false,
"showDelay": 0,
"hideDelay": 100,
"textStyle": {
"fontSize": 14
},
"borderWidth": 0,
"padding": 5
},
"title": [
{
"text": "\u8bb8\u5d69\u7684\u6b4c\u8bcd\u60c5\u611f\u5206\u6790",
"padding": 5,
"itemGap": 10
}
]
};
chart_7b066e6726024f9083cb49d258892ad7.setOption(option_7b066e6726024f9083cb49d258892ad7);
</script>
</body>
</html>