Matplotlib小提琴图颜色设置:全面指南与实用技巧
参考:Changing the Color of Matplotlib Violin Plots
小提琴图是一种强大的数据可视化工具,它能够直观地展示数据分布的形状和密度。在Matplotlib中,我们可以通过调整小提琴图的颜色来增强图表的可读性和美观性。本文将详细介绍如何在Matplotlib中更改小提琴图的颜色,包括单色设置、多色设置、渐变色应用以及自定义配色方案等多个方面。
1. 基础小提琴图绘制
在开始更改颜色之前,让我们先了解如何绘制一个基本的小提琴图。以下是一个简单的示例:
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
data = [np.random.normal(0, std, 100) for std in range(1, 4)]
# 创建图形和坐标轴
fig, ax = plt.subplots(figsize=(10, 6))
# 绘制小提琴图
violin_parts = ax.violinplot(data, showmeans=True, showmedians=True)
# 设置标题和标签
ax.set_title('Basic Violin Plot - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
Output:
在这个例子中,我们创建了三组正态分布的数据,并使用violinplot
函数绘制了小提琴图。showmeans=True
和showmedians=True
参数用于显示均值和中位数。
2. 更改小提琴图的整体颜色
要更改小提琴图的整体颜色,我们可以使用violinplot
函数返回的对象来设置颜色。以下是一个将小提琴图设置为蓝色的例子:
import matplotlib.pyplot as plt
import numpy as np
data = [np.random.normal(0, std, 100) for std in range(1, 4)]
fig, ax = plt.subplots(figsize=(10, 6))
violin_parts = ax.violinplot(data, showmeans=True, showmedians=True)
# 设置小提琴图的颜色
for pc in violin_parts['bodies']:
pc.set_facecolor('blue')
pc.set_edgecolor('black')
violin_parts['cmeans'].set_color('red')
violin_parts['cmedians'].set_color('green')
ax.set_title('Blue Violin Plot - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
Output:
在这个例子中,我们遍历了violin_parts['bodies']
列表,并使用set_facecolor
方法将每个小提琴的填充颜色设置为蓝色。我们还使用set_edgecolor
方法将边缘颜色设置为黑色。此外,我们还将均值和中位数的颜色分别设置为红色和绿色。
3. 为每个小提琴设置不同的颜色
如果我们想为每个小提琴设置不同的颜色,可以使用一个颜色列表。以下是一个示例:
import matplotlib.pyplot as plt
import numpy as np
data = [np.random.normal(0, std, 100) for std in range(1, 4)]
fig, ax = plt.subplots(figsize=(10, 6))
violin_parts = ax.violinplot(data, showmeans=True, showmedians=True)
colors = ['red', 'green', 'blue']
for i, pc in enumerate(violin_parts['bodies']):
pc.set_facecolor(colors[i])
pc.set_edgecolor('black')
ax.set_title('Multi-colored Violin Plot - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
Output:
在这个例子中,我们定义了一个颜色列表colors
,然后在遍历小提琴体时,使用索引i
来为每个小提琴选择不同的颜色。
4. 使用颜色映射(Colormap)
Matplotlib提供了丰富的颜色映射,我们可以利用这些映射来为小提琴图创建渐变色效果。以下是一个使用”viridis”颜色映射的例子:
import matplotlib.pyplot as plt
import numpy as np
data = [np.random.normal(0, std, 100) for std in range(1, 6)]
fig, ax = plt.subplots(figsize=(12, 6))
violin_parts = ax.violinplot(data, showmeans=True, showmedians=True)
# 使用viridis颜色映射
cmap = plt.get_cmap('viridis')
colors = [cmap(i/4) for i in range(5)]
for i, pc in enumerate(violin_parts['bodies']):
pc.set_facecolor(colors[i])
pc.set_edgecolor('black')
ax.set_title('Violin Plot with Colormap - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
Output:
在这个例子中,我们使用plt.get_cmap('viridis')
获取了”viridis”颜色映射,然后创建了一个颜色列表,其中每个颜色都是从颜色映射中均匀选取的。这样可以创建一个平滑的颜色过渡效果。
5. 设置透明度
有时候,我们可能希望小提琴图具有一定的透明度,以便更好地展示重叠的部分。我们可以通过设置alpha
参数来实现这一点:
import matplotlib.pyplot as plt
import numpy as np
data = [np.random.normal(0, std, 100) for std in range(1, 4)]
fig, ax = plt.subplots(figsize=(10, 6))
violin_parts = ax.violinplot(data, showmeans=True, showmedians=True)
for pc in violin_parts['bodies']:
pc.set_facecolor('blue')
pc.set_edgecolor('black')
pc.set_alpha(0.6)
ax.set_title('Transparent Violin Plot - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
Output:
在这个例子中,我们使用set_alpha
方法将小提琴的透明度设置为0.6。这个值范围从0(完全透明)到1(完全不透明)。
6. 使用自定义颜色
除了使用预定义的颜色名称,我们还可以使用RGB或RGBA值来定义自定义颜色:
import matplotlib.pyplot as plt
import numpy as np
data = [np.random.normal(0, std, 100) for std in range(1, 4)]
fig, ax = plt.subplots(figsize=(10, 6))
violin_parts = ax.violinplot(data, showmeans=True, showmedians=True)
custom_colors = [(0.8, 0.2, 0.3), (0.2, 0.8, 0.3), (0.3, 0.2, 0.8)]
for i, pc in enumerate(violin_parts['bodies']):
pc.set_facecolor(custom_colors[i])
pc.set_edgecolor('black')
ax.set_title('Violin Plot with Custom Colors - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
Output:
在这个例子中,我们定义了一个包含三个RGB元组的列表custom_colors
。每个元组代表一个自定义颜色,值范围从0到1。
7. 设置填充样式
除了改变颜色,我们还可以更改小提琴的填充样式。Matplotlib提供了多种填充样式,如斜线、点状等:
import matplotlib.pyplot as plt
import numpy as np
data = [np.random.normal(0, std, 100) for std in range(1, 4)]
fig, ax = plt.subplots(figsize=(10, 6))
violin_parts = ax.violinplot(data, showmeans=True, showmedians=True)
patterns = ['/', '\\', '|']
for i, pc in enumerate(violin_parts['bodies']):
pc.set_facecolor('white')
pc.set_edgecolor('black')
pc.set_hatch(patterns[i])
ax.set_title('Violin Plot with Fill Patterns - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
Output:
在这个例子中,我们使用set_hatch
方法为每个小提琴设置了不同的填充样式。patterns
列表包含了三种不同的填充样式:斜线、反斜线和竖线。
8. 结合颜色和填充样式
我们可以将颜色和填充样式结合起来,创造出更加丰富的视觉效果:
import matplotlib.pyplot as plt
import numpy as np
data = [np.random.normal(0, std, 100) for std in range(1, 4)]
fig, ax = plt.subplots(figsize=(10, 6))
violin_parts = ax.violinplot(data, showmeans=True, showmedians=True)
colors = ['lightblue', 'lightgreen', 'lightpink']
patterns = ['/', '\\', '|']
for i, pc in enumerate(violin_parts['bodies']):
pc.set_facecolor(colors[i])
pc.set_edgecolor('black')
pc.set_hatch(patterns[i])
pc.set_alpha(0.8)
ax.set_title('Violin Plot with Colors and Patterns - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
Output:
在这个例子中,我们为每个小提琴设置了不同的背景颜色和填充样式,并添加了一定的透明度,创造出了一个既有颜色又有纹理的效果。
9. 使用渐变填充
我们可以使用Matplotlib的渐变填充功能来创建更加高级的颜色效果:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import LinearSegmentedColormap
data = [np.random.normal(0, std, 100) for std in range(1, 4)]
fig, ax = plt.subplots(figsize=(10, 6))
violin_parts = ax.violinplot(data, showmeans=True, showmedians=True)
# 创建自定义渐变色映射
colors = ['blue', 'white', 'red']
n_bins = 100
cmap = LinearSegmentedColormap.from_list('custom', colors, N=n_bins)
for pc in violin_parts['bodies']:
pc.set_facecolor('none')
pc.set_edgecolor('black')
# 应用渐变填充
collection = plt.collections.PatchCollection([pc], cmap=cmap)
collection.set_array(np.linspace(0, 1, n_bins))
ax.add_collection(collection)
ax.set_title('Violin Plot with Gradient Fill - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
在这个例子中,我们创建了一个从蓝色到白色再到红色的自定义渐变色映射。然后,我们使用PatchCollection
来应用这个渐变填充到每个小提琴上。
10. 根据数据值设置颜色
我们可以根据数据的某些统计特征(如均值或中位数)来设置小提琴的颜色:
import matplotlib.pyplot as plt
import numpy as np
data = [np.random.normal(i, 1, 100) for i in range(5)]
fig, ax = plt.subplots(figsize=(12, 6))
violin_parts = ax.violinplot(data, showmeans=True, showmedians=True)
# 计算每组数据的均值
means = [np.mean(d) for d in data]
# 创建颜色映射
cmap = plt.get_cmap('coolwarm')
colors = [cmap((mean - min(means)) / (max(means) - min(means))) for mean in means]
for i, pc in enumerate(violin_parts['bodies']):
pc.set_facecolor(colors[i])
pc.set_edgecolor('black')
ax.set_title('Violin Plot with Color Based on Mean - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
Output:
在这个例子中,我们首先计算了每组数据的均值,然后使用这些均值来从”coolwarm”颜色映射中选择颜色。这样,均值较低的小提琴会呈现冷色调,而均值较高的小提琴会呈现暖色调。
11. 添加颜色图例
当我们使用不同的颜色来表示不同的含义时,添加一个颜色图例可以帮助读者更好地理解图表:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Patch
data = [np.random.normal(0, std, 100) for std in range(1, 4)]
fig, ax = plt.subplots(figsize=(12, 6))
violin_parts = ax.violinplot(data, showmeans=True, showmedians=True)
colors = ['red', 'green', 'blue']
labels = ['Low', 'Medium', 'High']
for i, pc in enumerate(violin_parts['bodies']):
pc.set_facecolor(colors[i])
pc.set_edgecolor('black')
# 创建图例
legend_elements = [Patch(facecolor=color, edgecolor='black', label=label)
for color, label in zip(colors, labels)]
ax.legend(handles=legend_elements, title='Data Categories')
ax.set_title('Violin Plot with Color Legend - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
Output:
在这个例子中,我们使用matplotlib.patches.Patch
创建了图例元素,每个元素对应一种颜色和标签。然后,我们使用ax.legend()
方法添加了图例。
12. 设置边缘颜色和宽度
除了填充颜色,我们还可以自定义小提琴图的边缘颜色和宽度:
import matplotlib.pyplot as plt
import numpy as np
data = [np.random.normal(0, std, 100) for std in range(1, 4)]
fig, ax = plt.subplots(figsize=(10, 6))
violin_parts = ax.violinplot(data, showmeans=True, showmedians=True)
for pc in violin_parts['bodies']:
pc.set_facecolor('lightblue')
pc.set_edgecolor('darkblue')
pc.set_linewidth(2)
violin_parts['cmeans'].set_color('red')
violin_parts['cmedians'].set_color('green')
violin_parts['cmins'].set_color('orange')
violin_parts['cmaxes'].set_color('purple')
for partname in ['cmeans', 'cmedians', 'cmins', 'cmaxes']:
vp = violin_parts[partname]
vp.set_linewidth(2)
ax.set_title('Violin Plot with Custom Edge Colors - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
Output:
在这个例子中,我们使用set_edgecolor()
方法设置了边缘颜色,使用set_linewidth()
方法设置了边缘宽度。我们还为均值、中位数、最小值和最大值线条设置了不同的颜色和宽度。
13. 使用循环颜色
当我们需要绘制大量小提琴图时,手动指定每个颜色可能会很繁琐。我们可以使用Matplotlib的颜色循环来自动分配颜色:
import matplotlib.pyplot as plt
import numpy as np
data = [np.random.normal(0, std, 100) for std in range(1, 8)]
fig, ax = plt.subplots(figsize=(14, 6))
violin_parts = ax.violinplot(data, showmeans=True, showmedians=True)
for i, pc in enumerate(violin_parts['bodies']):
pc.set_facecolor(plt.cm.Set3(i / len(data)))
pc.set_edgecolor('black')
ax.set_title('Violin Plot with Cyclic Colors - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
Output:
在这个例子中,我们使用plt.cm.Set3
颜色映射和索引i / len(data)
来为每个小提琴自动分配颜色。这种方法可以轻松处理大量的数据集。
14. 创建分组小提琴图
有时我们需要创建分组的小提琴图,每组包含多个小提琴。在这种情况下,我们可以使用不同的颜色来区分不同的组:
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
np.random.seed(10)
data = [np.random.normal(0, std, 100) for std in range(1, 4)]
data2 = [np.random.normal(0, std, 100) for std in range(2, 5)]
fig, ax = plt.subplots(figsize=(12, 6))
# 绘制第一组小提琴图
pos1 = [1, 3, 5]
vp1 = ax.violinplot(data, positions=pos1, showmeans=True, showmedians=True)
# 绘制第二组小提琴图
pos2 = [2, 4, 6]
vp2 = ax.violinplot(data2, positions=pos2, showmeans=True, showmedians=True)
# 设置颜色
for pc in vp1['bodies']:
pc.set_facecolor('lightblue')
pc.set_edgecolor('darkblue')
for pc in vp2['bodies']:
pc.set_facecolor('lightgreen')
pc.set_edgecolor('darkgreen')
ax.set_title('Grouped Violin Plot - how2matplotlib.com')
ax.set_xlabel('Groups')
ax.set_ylabel('Values')
ax.set_xticks([1.5, 3.5, 5.5])
ax.set_xticklabels(['Group 1', 'Group 2', 'Group 3'])
plt.show()
Output:
在这个例子中,我们创建了两组小提琴图,并使用不同的颜色来区分它们。我们还调整了x轴的刻度和标签以更好地表示分组。
15. 使用颜色来表示数据密度
我们可以使用颜色的深浅来表示数据的密度,这样可以在视觉上更好地展示数据分布:
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats
# 生成示例数据
np.random.seed(10)
data = [np.random.normal(0, std, 1000) for std in range(1, 4)]
fig, ax = plt.subplots(figsize=(12, 6))
# 计算核密度估计
positions = range(1, len(data) + 1)
parts = ax.violinplot(data, positions, showmeans=True, showmedians=True)
for i, pc in enumerate(parts['bodies']):
xdata, ydata = pc.get_paths()[0].vertices.T
kde = stats.gaussian_kde(data[i])
colors = plt.cm.viridis(kde(ydata) / kde(ydata).max())
pc.set_facecolor('none')
pc.set_edgecolor('black')
ax.scatter(xdata, ydata, c=colors, s=1)
ax.set_title('Violin Plot with Density Coloring - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
Output:
在这个例子中,我们使用scipy.stats.gaussian_kde
计算了核密度估计,然后使用这个估计值来设置点的颜色。颜色的深浅表示数据密度的高低。
16. 创建水平方向的小提琴图
到目前为止,我们创建的都是垂直方向的小提琴图。我们也可以创建水平方向的小提琴图,并应用相同的颜色设置技巧:
import matplotlib.pyplot as plt
import numpy as np
data = [np.random.normal(0, std, 100) for std in range(1, 6)]
fig, ax = plt.subplots(figsize=(10, 8))
violin_parts = ax.violinplot(data, vert=False, showmeans=True, showmedians=True)
colors = plt.cm.Set3(np.linspace(0, 1, len(data)))
for i, pc in enumerate(violin_parts['bodies']):
pc.set_facecolor(colors[i])
pc.set_edgecolor('black')
ax.set_title('Horizontal Violin Plot - how2matplotlib.com')
ax.set_xlabel('Values')
ax.set_ylabel('Data Sets')
plt.show()
Output:
在这个例子中,我们在violinplot
函数中设置vert=False
来创建水平方向的小提琴图。我们还交换了x轴和y轴的标签以保持一致性。
17. 结合箱线图和小提琴图
我们可以将小提琴图和箱线图结合起来,以同时展示数据的分布和关键统计信息:
import matplotlib.pyplot as plt
import numpy as np
data = [np.random.normal(0, std, 100) for std in range(1, 5)]
fig, ax = plt.subplots(figsize=(12, 6))
# 绘制小提琴图
violin_parts = ax.violinplot(data, showmeans=False, showmedians=False)
# 设置小提琴图颜色
for i, pc in enumerate(violin_parts['bodies']):
pc.set_facecolor(plt.cm.Set3(i / len(data)))
pc.set_edgecolor('black')
pc.set_alpha(0.7)
# 绘制箱线图
box_parts = ax.boxplot(data, positions=range(1, len(data) + 1), widths=0.3, patch_artist=True)
# 设置箱线图颜色
for i, box in enumerate(box_parts['boxes']):
box.set_facecolor('white')
box.set_edgecolor('black')
ax.set_title('Combined Violin and Box Plot - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
Output:
在这个例子中,我们首先绘制了小提琴图,然后在其上叠加了箱线图。小提琴图使用了不同的颜色,而箱线图保持白色填充以便清晰显示。
18. 使用颜色来表示不同的数据子集
当我们的数据集包含多个子类别时,我们可以使用颜色来区分这些子类别:
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
np.random.seed(10)
data1 = np.random.normal(0, 1, 200)
data2 = np.random.normal(2, 1, 200)
data3 = np.random.normal(-1, 1.5, 200)
fig, ax = plt.subplots(figsize=(10, 6))
# 绘制小提琴图
violin_parts = ax.violinplot([data1, data2, data3], showmeans=True, showmedians=True)
# 设置颜色
colors = ['lightblue', 'lightgreen', 'lightpink']
labels = ['Category A', 'Category B', 'Category C']
for i, pc in enumerate(violin_parts['bodies']):
pc.set_facecolor(colors[i])
pc.set_edgecolor('black')
pc.set_alpha(0.7)
# 添加图例
handles = [plt.Rectangle((0,0),1,1, color=color) for color in colors]
ax.legend(handles, labels, title='Data Categories')
ax.set_title('Violin Plot with Color-Coded Categories - how2matplotlib.com')
ax.set_xlabel('Categories')
ax.set_ylabel('Values')
ax.set_xticks([1, 2, 3])
ax.set_xticklabels(labels)
plt.show()
Output:
在这个例子中,我们为三个不同的数据类别创建了小提琴图,并使用不同的颜色来区分它们。我们还添加了一个图例来解释颜色的含义。
19. 创建彩虹效果的小提琴图
为了创造更加引人注目的视觉效果,我们可以使用彩虹色谱来填充小提琴图:
import matplotlib.pyplot as plt
import numpy as np
data = [np.random.normal(0, std, 100) for std in range(1, 8)]
fig, ax = plt.subplots(figsize=(14, 6))
violin_parts = ax.violinplot(data, showmeans=True, showmedians=True)
# 创建彩虹色谱
cmap = plt.get_cmap('rainbow')
colors = [cmap(i) for i in np.linspace(0, 1, len(data))]
for i, pc in enumerate(violin_parts['bodies']):
pc.set_facecolor(colors[i])
pc.set_edgecolor('black')
pc.set_alpha(0.8)
ax.set_title('Rainbow Violin Plot - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
Output:
在这个例子中,我们使用plt.get_cmap('rainbow')
获取彩虹色谱,然后使用np.linspace(0, 1, len(data))
在色谱中均匀取样,为每个小提琴分配一个独特的颜色。
20. 使用颜色渐变来表示数据范围
我们可以使用颜色渐变来直观地表示数据的范围,例如从最小值到最大值:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import Normalize
data = [np.random.normal(i, 1, 100) for i in range(5)]
fig, ax = plt.subplots(figsize=(12, 6))
violin_parts = ax.violinplot(data, showmeans=True, showmedians=True)
# 计算所有数据的最小值和最大值
all_data = np.concatenate(data)
vmin, vmax = all_data.min(), all_data.max()
norm = Normalize(vmin=vmin, vmax=vmax)
cmap = plt.get_cmap('viridis')
for i, pc in enumerate(violin_parts['bodies']):
colors = cmap(norm(data[i]))
pc.set_facecolor(colors.mean(axis=0))
pc.set_edgecolor('black')
# 添加颜色条
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
cbar = plt.colorbar(sm)
cbar.set_label('Data Range')
ax.set_title('Violin Plot with Color Gradient - how2matplotlib.com')
ax.set_xlabel('Data Sets')
ax.set_ylabel('Values')
plt.show()
在这个例子中,我们使用Normalize
函数将数据值映射到0-1范围,然后使用这个映射来从颜色映射中选择颜色。我们还添加了一个颜色条来显示数值范围。
总结起来,Matplotlib提供了丰富的工具和选项来自定义小提琴图的颜色。通过调整填充颜色、边缘颜色、透明度,以及使用颜色映射和渐变,我们可以创建既美观又信息丰富的数据可视化。这些技巧不仅可以增强图表的视觉吸引力,还能帮助我们更有效地传达数据中的模式和趋势。
在实际应用中,选择合适的颜色方案对于数据的清晰呈现至关重要。以下是一些额外的建议:
- 考虑色盲友好的配色方案,确保你的图表对所有观众都易于理解。
-
使用对比度高的颜色来突出重要的数据点或趋势。
-
在科学或专业场合,尽量选择不会分散注意力的颜色方案,以保持专业性。
-
如果你的数据有自然的顺序或层次,考虑使用渐变色来反映这种结构。
-
当展示多个类别时,选择易于区分的颜色。
-
始终为你的颜色选择提供清晰的图例或说明。
最后,记住颜色只是数据可视化的一个方面。它应该与其他元素(如标题、标签、比例尺等)协同工作,共同创造一个清晰、准确且引人入胜的数据故事。通过不断实践和实验,你将能够掌握使用Matplotlib创建富有洞察力和视觉吸引力的小提琴图的艺术。
结语
本文详细介绍了如何在Matplotlib中更改小提琴图的颜色,涵盖了从基础的单色设置到高级的渐变和密度表示。我们探讨了多种技术,包括使用预定义的颜色、自定义RGB值、颜色映射、透明度设置、填充样式等。这些技巧不仅适用于小提琴图,也可以应用到其他类型的Matplotlib图表中。
通过灵活运用这些颜色设置技巧,你可以创建既美观又富有信息量的数据可视化。记住,好的数据可视化不仅要吸引眼球,更要清晰地传达数据中的信息和洞察。在选择颜色方案时,始终要考虑你的目标受众和数据的性质。
随着你在数据可视化领域的不断探索,你会发现颜色是一个强大的工具,可以帮助你讲述更加引人入胜的数据故事。继续实践,不断尝试新的ideas,你将能够创造出既美观又有洞察力的数据可视化作品。