1
# Libraries
import matplotlib.pyplot as plt
import pandas as pd
from math import pi
# 设置matplotlib的默认字体为SimHei(黑体),以支持中文显示
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定默认字体为SimHei
# 解决保存图像时负号'-'显示为方块的问题
plt.rcParams['axes.unicode_minus'] = False
# 设置数据
df = pd.DataFrame({
'group': ['A','B','C','D'], # 组别
'专业知识': [38, 1.5, 30, 4], # 各组的专业知识得分
'社交能力': [29, 10, 9, 34], # 各组的社交能力得分
'领导能力': [15, 39, 23, 24], # 各组的领导能力得分
'自我管理': [35, 31, 33, 14], # 各组的自我管理得分
'学习能力': [32, 15, 32, 14] # 各组的学习能力得分
})
# 获取变量的数量(即除了'group'列之外的其他列)
categories = list(df)[1:] # ['专业知识', '社交能力', '领导能力', '自我管理', '学习能力']
N = len(categories) # 变量的数量,这里是5
# 我们要绘制数据框的第一行数据(即A组的数据)
# 但为了闭合雷达图,我们需要将第一个值重复添加到列表的末尾
values = df.loc[0].drop('group').values.flatten().tolist() # 获取A组的数据并转换为列表
values += values[:1] # 将第一个值添加到列表末尾,以闭合雷达图
# 计算每个轴的角度(将圆分成N等份)
angles = [n / float(N) * 2 * pi for n in range(N)] # 计算每个变量的角度
angles += angles[:1] # 将第一个角度添加到列表末尾,以闭合雷达图
# 初始化雷达图
ax = plt.subplot(111, polar=True) # 创建一个极坐标子图
# 绘制每个变量的轴线,并添加标签
plt.xticks(angles[:-1], categories, color='grey', size=8) # 设置每个轴的角度和标签
# 设置y轴的标签位置和刻度
ax.set_rlabel_position(0) # 设置y轴标签的位置
plt.yticks([10,20,30], ["10","20","30"], color="grey", size=7) # 设置y轴刻度
plt.ylim(0,40) # 设置y轴的范围为0到40
# 绘制数据
ax.plot(angles, values, linewidth=1, linestyle='solid') # 绘制A组的数据
# 填充区域
ax.fill(angles, values, 'b', alpha=0.1) # 填充A组数据的区域,颜色为蓝色,透明度为0.1
# 显示图形
plt.show()
编写这段代码的过程,如同在数据的海洋中绘制一幅星图,每一个变量是星辰,每一组数据是星座。通过 `matplotlib` 的画笔,我将抽象的数字转化为极坐标系下的雷达图,让数据在视觉中绽放。调试时的困惑如同迷雾,而最终图形的呈现,则是迷雾散尽后的璀璨星空。这段代码不仅让我领略了编程的力量,更让我感受到数据与艺术的交融——每一行代码都是对逻辑的雕琢,每一处细节都是对美学的追求。编程,不仅是技术的实现,更是对世界的另一种表达。
2
```python
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Circle, RegularPolygon
from matplotlib.path import Path
from matplotlib.projections import register_projection
from matplotlib.projections.polar import PolarAxes
from matplotlib.spines import Spine
from matplotlib.transforms import Affine2D
```
- **作用**:导入所需的库和模块。
- `matplotlib.pyplot`:用于绘图。
- `numpy`:用于数值计算。
- `matplotlib.patches`:用于绘制图形(如圆形和多边形)。
- `matplotlib.path`:用于定义路径。
- `matplotlib.projections`:用于自定义坐标系。
- `matplotlib.spines`:用于绘制坐标轴。
- `matplotlib.transforms`:用于坐标变换。
---
### 2. **定义 `radar_factory` 函数**
```python
def radar_factory(num_vars, frame='circle'):
"""
Create a radar chart with `num_vars` Axes.
This function creates a RadarAxes projection and registers it.
"""
# 计算均匀分布的角度
theta = np.linspace(0, 2*np.pi, num_vars, endpoint=False)
```
- **作用**:创建一个雷达图的坐标系。
- **参数**:
- `num_vars`:雷达图的变量数量。
- `frame`:坐标系的外框形状(`circle` 或 `polygon`)。
- **返回值**:均匀分布的角度 `theta`。
---
### 3. **定义 `RadarTransform` 类**
```python
class RadarTransform(PolarAxes.PolarTransform):
def transform_path_non_affine(self, path):
if path._interpolation_steps > 1:
path = path.interpolated(num_vars)
return Path(self.transform(path.vertices), path.codes)
```
- **作用**:自定义极坐标系的路径变换,确保路径在雷达图中正确显示。
---
### 4. **定义 `RadarAxes` 类**
```python
class RadarAxes(PolarAxes):
name = 'radar'
PolarTransform = RadarTransform
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 将第一个轴旋转到顶部
self.set_theta_zero_location('N')
```
- **作用**:自定义雷达图的坐标系。
- **功能**:
- 设置雷达图的名称和变换。
- 初始化时将第一个轴旋转到顶部。
---
### 5. **重写 `fill` 和 `plot` 方法**
```python
def fill(self, *args, closed=True, **kwargs):
return super().fill(closed=closed, *args, **kwargs)
def plot(self, *args, **kwargs):
lines = super().plot(*args, **kwargs)
for line in lines:
self._close_line(line)
```
- **作用**:确保雷达图的填充和线条默认闭合。
---
### 6. **定义 `_close_line` 方法**
```python
def _close_line(self, line):
x, y = line.get_data()
if x[0] != x[-1]:
x = np.append(x, x[0])
y = np.append(y, y[0])
line.set_data(x, y)
```
- **作用**:闭合雷达图的线条。
---
### 7. **定义 `set_varlabels` 方法**
```python
def set_varlabels(self, labels):
self.set_thetagrids(np.degrees(theta), labels)
```
- **作用**:设置雷达图的变量标签。
---
### 8. **定义 `_gen_axes_patch` 方法**
```python
def _gen_axes_patch(self):
if frame == 'circle':
return Circle((0.5, 0.5), 0.5)
elif frame == 'polygon':
return RegularPolygon((0.5, 0.5), num_vars, radius=.5, edgecolor="k")
else:
raise ValueError("Unknown value for 'frame': %s" % frame)
```
- **作用**:生成雷达图的外框(圆形或多边形)。
---
### 9. **定义 `_gen_axes_spines` 方法**
```python
def _gen_axes_spines(self):
if frame == 'circle':
return super()._gen_axes_spines()
elif frame == 'polygon':
spine = Spine(axes=self, spine_type='circle',
path=Path.unit_regular_polygon(num_vars))
spine.set_transform(Affine2D().scale(.5).translate(.5, .5) + self.transAxes)
return {'polar': spine}
else:
raise ValueError("Unknown value for 'frame': %s" % frame)
```
- **作用**:生成雷达图的坐标轴。
---
### 10. **注册自定义坐标系**
```python
register_projection(RadarAxes)
return theta
```
- **作用**:注册 `RadarAxes` 为自定义坐标系,并返回角度 `theta`。
---
### 11. **定义 `example_data` 函数**
```python
def example_data():
data = [
['Sulfate', 'Nitrate', 'EC', 'OC1', 'OC2', 'OC3', 'OP', 'CO', 'O3'],
('Basecase', [...]),
('With CO', [...]),
('With O3', [...]),
('CO & O3', [...])
]
return data
```
- **作用**:提供示例数据,用于绘制雷达图。
---
### 12. **主程序**
```python
if __name__ == '__main__':
N = 9
theta = radar_factory(N, frame='polygon')
data = example_data()
spoke_labels = data.pop(0)
fig, axs = plt.subplots(figsize=(9, 9), nrows=2, ncols=2,
subplot_kw=dict(projection='radar'))
fig.subplots_adjust(wspace=0.25, hspace=0.20, top=0.85, bottom=0.05)
colors = ['b', 'r', 'g', 'm', 'y']
for ax, (title, case_data) in zip(axs.flat, data):
ax.set_rgrids([0.2, 0.4, 0.6, 0.8])
ax.set_title(title, weight='bold', size='medium', position=(0.5, 1.1),
horizontalalignment='center', verticalalignment='center')
for d, color in zip(case_data, colors):
ax.plot(theta, d, color=color)
ax.fill(theta, d, facecolor=color, alpha=0.25, label='_nolegend_')
ax.set_varlabels(spoke_labels)
labels = ('Factor 1', 'Factor 2', 'Factor 3', 'Factor 4', 'Factor 5')
legend = axs[0, 0].legend(labels, loc=(0.9, .95),
labelspacing=0.1, fontsize='small')
fig.text(0.5, 0.965, '5-Factor Solution Profiles Across Four Scenarios',
horizontalalignment='center', color='black', weight='bold',
size='large')
plt.show()
编写这段代码的过程,如同在数据的星空中绘制一幅极坐标的星图,每一个变量是一颗星辰,每一组数据是一个星座。通过自定义 `RadarAxes`,我突破了 `matplotlib` 的默认限制,实现了灵活的雷达图绘制。闭合线条、角度计算、外框形状等细节的打磨,让我深刻体会到可视化中“细节决定成败”的真谛。代码的模块化设计不仅提高了可读性,还让功能更易于扩展和复用。调试过程中,耐心和细致帮助我解决了线条未闭合、标签错位等问题,也让我更加理解了工具的强大与灵活。最终,当雷达图在屏幕上绽放时,数据的故事通过颜色、填充和标签生动展现,那种成就感让我感受到编程不仅是技术的实现,更是一种艺术化的表达。这段经历让我明白,数据可视化不仅是分析的工具,更是连接数据与洞察的桥梁,而编程则是实现这一桥梁的魔法。
3
import tushare as ts
import mplfinance as mpf
from pylab import mpl
import pandas as pd
pro = ts.pro_api('(你自己的)') #
#https://tushare.pro/user/token
df = pro.daily(ts_code='600519.SH', start_date='20200101', end_date='20250319')
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
df['close'].plot(title='贵州茅台股价走势图')
通过Tushare高效获取金融数据,结合Matplotlib绘制清晰股价趋势图,并在解决中文显示问题的过程中,深刻体会到数据可视化是连接原始数据与直观洞察的桥梁。