将两个绘图折线图添加到同一个facetgrid图 - python

问题描述 投票:0回答:1

我正在尝试使用不同的 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:

python plotly facet-grid
1个回答
0
投票

要自定义线条样式,您将需要使用图形对象。在本问题中,您希望使两个 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()

© www.soinside.com 2019 - 2024. All rights reserved.