我正在尝试使用不同的 y 值将两条单独的迹线添加到完全相同的面网格图。该图使用
facet_col
来分隔基于 color
的子图。对于每个子图,x 轴将 cut
显示为分类变量。我有两个与价格相关的单独列(price
,price2
)。
我想在同一个facetgrid布局中绘制这两个值。但
price2
迹线应显示为虚线
1)。它们单独工作,但当尝试将它们组合成一个图形时,facetgrid 布局将被忽略并返回单个图。
2)。在一次调用中组合 y 值时,我通过在
price2
上应用虚线来区分它们。但随后颜色序列丢失并且图例未更新。
import seaborn as sns
import plotly.express as px
import plotly.graph_objects as go
import numpy as np
diamonds = sns.load_dataset('diamonds')
diamonds['val'] = np.random.randint(1, 3, diamonds.shape[0])
diamonds['price2'] = diamonds['price'] + 5000
diamonds = diamonds.drop_duplicates(subset = ['cut','color'])
color_discrete_sequence = px.colors.qualitative.G10
fig1 = px.line(diamonds,
x = "cut",
y = "price",
color = "val",
facet_col = "color",
facet_col_wrap = 3,
facet_row_spacing = 0.08,
facet_col_spacing = 0.08,
markers = True,
color_discrete_sequence = color_discrete_sequence,
category_orders = {"cut": ['E', 'I', 'J', 'H', 'F', 'G', 'D']}
)
fig2 = px.line(diamonds,
x = "cut",
y = "price2",
color = "val",
facet_col = "color",
facet_col_wrap = 3,
facet_row_spacing = 0.08,
facet_col_spacing = 0.08,
markers = True,
color_discrete_sequence = color_discrete_sequence,
category_orders = {"cut": ['E', 'I', 'J', 'H', 'F', 'G', 'D']}
)
#update y-values for price2 only to be dashed
fig2.update_traces(patch={"line": {"dash": 'dot'}})
fig1_2 = go.Figure(data = fig1.data + fig2.data)
fig1_2.show()
2)
fig = px.line(diamonds,
x = "cut",
y = ["price","price2"],
color = "val",
facet_col = "color",
facet_col_wrap = 3,
facet_row_spacing = 0.08,
facet_col_spacing = 0.08,
markers = True,
color_discrete_sequence = color_discrete_sequence,
category_orders = {"cut": ['E', 'I', 'J', 'H', 'F', 'G', 'D']}
)
for i in range(1,28,2):
fig.data[i]['line'] = dict(dash='dot')
fig.show()
编辑3:
要自定义线条样式,您将需要使用图形对象。在本问题中,您希望使两个 y 值中的每一个都成为不同的线型,因此可以通过以下方式实现此目的。
import seaborn as sns
import numpy as np
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import itertools
np.random.seed(20231129)
diamonds = sns.load_dataset('diamonds')
diamonds['val'] = np.random.randint(1, 3, diamonds.shape[0])
diamonds['price2'] = diamonds['price'] + 1000
diamonds = diamonds.drop_duplicates(subset = ['cut','color'])
lst = itertools.product(range(1,5),range(1,4))
colors = ['E', 'I', 'J', 'H', 'F', 'G', 'D']
sub_titles = [f'color={c}' for c in colors]
fig = make_subplots(rows=4, cols=3,
start_cell="top-left",
shared_yaxes=True,
#shared_xaxes=True,
subplot_titles=sub_titles,
)
for c,rc in zip(colors, lst):
df_color = diamonds.query('color == @c')
df_color.set_index('cut', inplace=True)
df_color = df_color.reindex(index=['Ideal','Fair','Very Good','Premium','Good'])
df_color.reset_index(inplace=True)
for v in df_color['val'].unique():
df = df_color.query('val == @v')
if v == 1:
color = 'blue'
# dash = 'dot'
else:
color = 'red'
# dash = 'dot'
fig.add_trace(go.Scatter(
x=df['cut'],
y=df['price'],
mode='markers+lines',
marker=dict(color=color),
line=dict(dash='solid'),
name=f'{v}'
), row=rc[0],col=rc[1])
fig.add_trace(go.Scatter(
x=df['cut'],
y=df['price2'],
mode='markers+lines',
marker=dict(color=color),
line=dict(dash='dot'),
name=f'{v}'
), row=rc[0],col=rc[1])
names = set()
fig.for_each_trace(
lambda trace:
trace.update(showlegend=False)
if (trace.name in names) else names.add(trace.name))
# update xaxis and yaxis titles
fig.layout['xaxis7']['title']['text']='cut'
fig.layout['yaxis']['title']['text']='Value'
fig.layout['yaxis4']['title']['text']='Value'
fig.layout['yaxis7']['title']['text']='Value'
fig.update_layout(height=450)
fig.show()