【发布时间】:2021-11-07 03:32:43
【问题描述】:
我正在尝试使用 python 3.8.10 和 matplotlib 3.3.4 制作小提琴图
import matplotlib.pyplot as plt
import numpy as np
data = []
data.append([65,46,64,59,42,44])
data.append([20,40,44,43,32,20,27,31,20,40,24,26,37,30,29,25,31,65,50,38,41,19,31,38,48,44,51,55,52,25,40,28,50,37,44,21,43,28,36,67,55,58,23,36,28,21,21,39,26,65,18,27,50,70,29,37,25,49,33,31,20,33])
f = plt.figure()
plt.rc('xtick', labelsize = 6)
violin_plot = plt.violinplot(data, showmeans=False, showmedians=False)
for pc in violin_plot["bodies"]:
pc.set_edgecolor('black')
def adjacent_values(vals, q1, q3):
upper_adjacent_value = q3 + (q3 - q1) * 1.5
upper_adjacent_value = np.clip(upper_adjacent_value, q3, vals[-1])
lower_adjacent_value = q1 - (q3 - q1) * 1.5
lower_adjacent_value = np.clip(lower_adjacent_value, vals[0], q1)
return lower_adjacent_value, upper_adjacent_value
quartile1, medians, quartile3 = np.percentile(data, [25, 50, 75], axis=1)
whiskers = np.array([
adjacent_values(sorted_array, q1, q3)
for sorted_array, q1, q3 in zip(data, quartile1, quartile3)])
whiskers_min, whiskers_max = whiskers[:, 0], whiskers[:, 1]
inds = np.arange(1, len(medians) + 1)
plt.scatter(inds, medians, marker="o", color="white", s=30, zorder=3)
plt.vlines(inds, quartile1, quartile3, color="k", linestyle="-", lw=5)
plt.vlines(inds, whiskers_min, whiskers_max, color="k", linestyle="-", lw=1)
plt.savefig('violin_age_by_race.svg', bbox_inches='tight', pad_inches = 0.05)
我从https://matplotlib.org/devdocs/gallery/statistics/customized_violin.html得到的
但上面的代码会产生错误(行号与上面的代码不同,因为我将文件剪掉了,以便为 StackOverflow 制作一个最小的工作示例)
/usr/local/lib/python3.8/dist-packages/numpy/core/_asarray.py:171: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray.
return array(a, dtype, copy=False, order=order, subok=True)
Traceback (most recent call last):
File "/tmp/E2Woujgas1.py", line 35, in <module>
quartile1, medians, quartile3 = np.percentile(data, [25, 50, 75], axis=1)
File "<__array_function__ internals>", line 5, in percentile
File "/usr/local/lib/python3.8/dist-packages/numpy/lib/function_base.py", line 3818, in percentile
return _quantile_unchecked(
File "/usr/local/lib/python3.8/dist-packages/numpy/lib/function_base.py", line 3937, in _quantile_unchecked
r, k = _ureduce(a, func=_quantile_ureduce_func, q=q, axis=axis, out=out,
File "/usr/local/lib/python3.8/dist-packages/numpy/lib/function_base.py", line 3495, in _ureduce
axis = _nx.normalize_axis_tuple(axis, nd)
File "/usr/local/lib/python3.8/dist-packages/numpy/core/numeric.py", line 1391, in normalize_axis_tuple
axis = tuple([normalize_axis_index(ax, ndim, argname) for ax in axis])
File "/usr/local/lib/python3.8/dist-packages/numpy/core/numeric.py", line 1391, in <listcomp>
axis = tuple([normalize_axis_index(ax, ndim, argname) for ax in axis])
numpy.AxisError: axis 1 is out of bounds for array of dimension 1
错误在quartile1, medians, quartile3 = np.percentile(data, [25, 50, 75], axis=1),所以我按照错误消息的提示进行操作,然后更改为
quartile1, medians, quartile3 = np.percentile(data, [25, 50, 75], axis=1, dtype = object)
然后我得到一个错误:
TypeError: _percentile_dispatcher() got an unexpected keyword argument 'dtype'
据我所知,由于子列表的长度不同,因此引发了错误,这是不可避免的。该示例包含所有包含 100 个元素的子列表。
我也尝试过创建一个 np 数组:
np_data = np.array(data, dtype = object)
quartile1, medians, quartile3 = np.percentile(np_data, [25, 50, 75], axis=1, dtype = object)
但上述更改给出了关于dtype的相同错误
如何更改此代码以使 numpy 不会抱怨不同长度的子列表?
【问题讨论】:
-
为什么在调用
percentile的时候还继续使用dtype=object?之前的电话已经告诉你这是错误的!
标签: python python-3.x numpy matplotlib