【问题标题】:Plot 1D-data on 2D with discrete X-Axis values as labels in Python在 Python 中以离散 X 轴值作为标签在 2D 上绘制 1D 数据
【发布时间】:2021-09-03 07:01:10
【问题描述】:

我有一个 15 行的 csv,每行有 50 个值,即 50 列。 第一行,即标题具有值的标签/名称。

文件看起来像这样(填充了 50 列,15 行,一些值是 nan):

label1, label2, label3, ..., label50
0123, 345, nan, ..., 287
4324, nan, 343, ..., 362
...

我想垂直绘制每一列的值。 对于 15 行,包括标题 = 一个水平 x 值(即标签)上的 14 个值。 这样我的 X 轴是离散的,标签名称作为值。

一种有效但仅适用于箱线图而非散点图的方法如下(有关图像,请参阅https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.boxplot.html):

df = pd.read_csv("data.csv", delimiter=",") 
df.plot.box()  # plots boxplot with discrete x-axis values as labels
plt.xticks(rotation=90, ha='right')  # label names are 90 degree turned on x-axis
plt.yscale(log) # logscale for my dataset
plt.show()

我希望得到与箱线图相同的结果。但是,我希望看到垂直分布的列的每个点而不是框,并且如果可能的话,csv 的每一行都以独特的颜色显示,以便在图表中将行彼此分开。 (一行是数据点的一个“组合”)

作为一个初学者,我还没有找到解决方案...

提前非常感谢。如果您不理解我的解释,请随时询问。

【问题讨论】:

  • 感谢您的回复!我将“名称”列添加到我的 csv 中。着色工作!但我不想要线条,而是想要点。你知道用点而不是线来绘制它的方法吗?

标签: python pandas matplotlib seaborn


【解决方案1】:

你可以试试 pandas 的parallel_coordinates。您需要添加一个额外的列来为每一行提供一个唯一的标签。您可以删除线型并使用点作为标记:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randint(1, 100, (15, 50)).astype(float), columns=[f'lbl{i}' for i in range(1, 51)])
df['Name'] = [f'row{i}' for i in range(len(df))]
fig, ax = plt.subplots(figsize=(25, 8))
pd.plotting.parallel_coordinates(df, 'Name', color=plt.cm.tab20(np.arange(len(df))), ls='', marker='o', ax=ax)
ax.legend(bbox_to_anchor=(1.01, 1.02), loc='upper left')
plt.tight_layout()
plt.show()

PS:如果不需要垂直线,您可以使用pd.plotting.parallel_coordinates(..., axvlines=False)ax.grid(False, axis='x')ax.tick_params(axis='x', rotation=30) 会将 x 标签旋转 30 度。

这是另一个例子,它也设置了一些左右边距。

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randint(1, 10, (15, 50)).astype(float).cumsum(axis=0), columns=[f'lbl{i}' for i in range(1, 51)])
df['Name'] = [f'row{i}' for i in range(len(df))]
fig, ax = plt.subplots(figsize=(15, 8))
pd.plotting.parallel_coordinates(df, 'Name', color=plt.cm.turbo(np.linspace(0, 1, len(df)) ), ls='', marker='o', axvlines=False, ax=ax)
ax.legend(bbox_to_anchor=(1.01, 1.02), loc='upper left')
ax.grid(False)
ax.tick_params(axis='x', rotation=30)
ax.autoscale()
ax.margins(x=0.01)
plt.tight_layout()
plt.show()

【讨论】:

  • 谢谢!这就是解决方案。我还有一个问题,如何删除水平网格线? :D
  • ax.grid(False) 删除所有网格线
猜你喜欢
  • 1970-01-01
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
  • 2021-11-05
  • 1970-01-01
  • 2019-10-26
相关资源
最近更新 更多