我有一个情节,每条线都用变量a的值着色,并且线条样式乘以变量b的值:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# some data
x = np.array([[1, 2, 0.1, 0.5], [2, 3, 0.1, 0.5],
[1, 4, 0.4, 0.8], [2, 1, 0.4, 0.8],
[1, 1, 0.1, 0.8], [2, 3, 0.1, 0.8],
[1, 3, 0.4, 0.5], [2, 3, 0.4, 0.5]])
df = pd.DataFrame(x)
df.columns = ["x", "y", "a", "b"]
df.head()
# define color scheme and line style
colors = ["C1", "C2", "C3"]
linestyles = ['-', "--", ":"]
for a_idx, a in enumerate(np.unique(df["a"])):
for b_idx, b in enumerate(np.unique(df["b"])):
df2 = df[df["a"] == a]
df2 = df2[df2["b"] == b]
plt.plot(df2["x"], df2["y"], c = colors[a_idx], ls = linestyles[b_idx])
plt.legend(['a = 0.1, b = 0.5', 'a = 0.1, b = 0.8',
'a = 0.4, b = 0.5', 'a = 0.4, b = 0.8'])
plt.show()
现在我想要有颜色和线条样式的单独图例,所以一个标题为a的框和两个颜色为0.1,0.4的颜色的框和另一个标题为b的框和两个颜色为0.5和0.8的不同线条的线。
只有一个盒子也可以,但是有一些空格可以分开颜色和线条样式。
答案 0 :(得分:4)
你可以做这样的事情
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# some data
x = np.array([[1, 2, 0.1, 0.5], [2, 3, 0.1, 0.5],
[1, 4, 0.4, 0.8], [2, 1, 0.4, 0.8],
[1, 1, 0.1, 0.8], [2, 3, 0.1, 0.8],
[1, 3, 0.4, 0.5], [2, 3, 0.4, 0.5]])
df = pd.DataFrame(x)
df.columns = ["x", "y", "a", "b"]
df.head()
# define color scheme and line style
colors = ["C1", "C2", "C3"]
linestyles = ['-', "--", ":"]
fig, axes = plt.subplots()
for a_idx, a in enumerate(np.unique(df["a"])):
for b_idx, b in enumerate(np.unique(df["b"])):
df2 = df[df["a"] == a]
df2 = df2[df2["b"] == b]
axes.plot(df2["x"], df2["y"], c = colors[a_idx], ls = linestyles[b_idx])
#dummy lines with NO entries, just to create the black style legend
dummy_lines = []
for b_idx, b in enumerate(np.unique(df["b"])):
dummy_lines.append(axes.plot([],[], c="black", ls = linestyles[b_idx])[0])
lines = axes.get_lines()
legend1 = plt.legend([lines[i] for i in [0,2]], ["a = 0.1", "a = 0.4"], loc=1)
legend2 = plt.legend([dummy_lines[i] for i in [0,1]], ["b = 0.5", "b = 0.8"], loc=4)
axes.add_artist(legend1)
plt.show()
基本思想是通过调用plt.legend()
和axes.add_artist()
而不是仅调用plt.legend()来添加自己的图例。这允许您根据需要添加任意数量的图例。现在您只需选择与每个图表关联的行,并为每个图例中的每个条目设置标题。
要为不同的样式创建黑色图例,我们必须添加“虚拟”线,这些线不包含单个点(因此它们在图中本身不可见,但可以在图例中引用以更改颜色)。这是有效的,但似乎是一个古怪的黑客。对于小例子,这将没有任何问题,但对于大型项目,这不是最佳解决方案;所以,如果有人知道更好的解决方案,请告诉我!
这会创建此情节
答案 1 :(得分:2)
我使用ggplot(使用默认颜色)找到了一种更简单的方法。
import pandas as pd
import numpy as np
from ggplot import *
x = np.array([[1, 2, 0.1, 0.5], [2, 3, 0.1, 0.5],
[1, 4, 0.4, 0.8], [2, 1, 0.4, 0.8],
[1, 1, 0.1, 0.8], [2, 3, 0.1, 0.8],
[1, 3, 0.4, 0.5], [2, 3, 0.4, 0.5]])
df = pd.DataFrame(x)
df.columns = ["x", "y", "a", "b"]
# convert a and b to categorical variables
df["a"] = df["a"].astype('category')
df["b"] = df["b"].astype('category')
ggplot(df, aes("x", "y", color = "a", linetype = "b")) + geom_line() + theme_bw()
诀窍是将a和b转换为分类变量。然后ggplot会自动添加两个图例。