Plotly:如何在带有刻面的图形表达图形中隐藏轴标题?

Ran*_*win 7 python facet express axis-labels plotly

有没有一种简单的方法可以使用 plotly express 在分面图中隐藏重复的轴标题?我试过设置

visible=True
Run Code Online (Sandbox Code Playgroud)

在下面的代码中,但这也隐藏了 y 轴刻度标签(值)。理想情况下,我想将隐藏重复轴标题设置为一般多面图的默认值(或者甚至更好,只是默认为整个多面图显示单个 x 和 y 轴标题。

下面是测试代码:

import pandas as pd
import numpy as np
import plotly.express as px
import string

# create a dataframe
cols = list(string.ascii_letters)
n = 50

df = pd.DataFrame({'Date': pd.date_range('2021-01-01', periods=n)})

# create data with vastly different ranges
for col in cols:
    start = np.random.choice([1, 10, 100, 1000, 100000])
    s = np.random.normal(loc=0, scale=0.01*start, size=n)
    df[col] = start + s.cumsum()

# melt data columns from wide to long
dfm = df.melt("Date")

fig = px.line(
    data_frame=dfm,
    x = 'Date',
    y = 'value',
    facet_col = 'variable',
    facet_col_wrap=6,
    facet_col_spacing=0.05,
    facet_row_spacing=0.035,
    height = 1000,
    width = 1000,
    title = 'Value vs. Date'
)

fig.update_yaxes(matches=None, showticklabels=True, visible=True)
fig.update_annotations(font=dict(size=16))
fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

最终代码(接受的答案)。注意情节 >= 4.9

import pandas as pd
import numpy as np
import plotly.express as px
import string
import plotly.graph_objects as go

# create a dataframe
cols = list(string.ascii_letters)
n = 50

df = pd.DataFrame({'Date': pd.date_range('2021-01-01', periods=n)})

# create data with vastly different ranges
for col in cols:
    start = np.random.choice([1, 10, 100, 1000, 100000])
    s = np.random.normal(loc=0, scale=0.01*start, size=n)
    df[col] = start + s.cumsum()

# melt data columns from wide to long
dfm = df.melt("Date")

fig = px.line(
    data_frame=dfm,
    x = 'Date',
    y = 'value',
    facet_col = 'variable',
    facet_col_wrap=6,
    facet_col_spacing=0.05,
    facet_row_spacing=0.035,
    height = 1000,
    width = 1000,
    title = 'Value vs. Date'
)

fig.update_yaxes(matches=None, showticklabels=True, visible=True)
fig.update_annotations(font=dict(size=16))
fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))

# hide subplot y-axis titles and x-axis titles
for axis in fig.layout:
    if type(fig.layout[axis]) == go.layout.YAxis:
        fig.layout[axis].title.text = ''
    if type(fig.layout[axis]) == go.layout.XAxis:
        fig.layout[axis].title.text = ''
        
# keep all other annotations and add single y-axis and x-axis title:
fig.update_layout(
    # keep the original annotations and add a list of new annotations:
    annotations = list(fig.layout.annotations) + 
    [go.layout.Annotation(
            x=-0.07,
            y=0.5,
            font=dict(
                size=16, color = 'blue'
            ),
            showarrow=False,
            text="single y-axis title",
            textangle=-90,
            xref="paper",
            yref="paper"
        )
    ] +
    [go.layout.Annotation(
            x=0.5,
            y=-0.08,
            font=dict(
                size=16, color = 'blue'
            ),
            showarrow=False,
            text="Dates",
            textangle=-0,
            xref="paper",
            yref="paper"
        )
    ]
)

fig.show()
Run Code Online (Sandbox Code Playgroud)

Ran*_*win 8

作为对此的旁注,我发现了一种更直接的方法,可以使用 labels 参数从plotly express 调用中消除轴标签,并为我想要消除的标签提供值为 '' 的标签字典。

虽然这不会导致在整个图形级别上出现单个标签,但如果图形标题对“Y vs. X”有足够的描述性,那么也许缺少轴标签可以“原谅”?(或如 @vestland 所示添加)

请注意,您可以“几乎”消除每个子批次中具有“=值”的烦人的重复方面标题。即,如果您向标签字典中再添加一项:

'多变的': ''

然后,您无需获取“variable=variable level”,而只需获取facet 变量级别,前面带有“=”,如下图所示。

完整代码

import pandas as pd
import numpy as np
import plotly.express as px
import string

# create a dataframe
cols = list(string.ascii_letters)
n = 50

df = pd.DataFrame({'Date': pd.date_range('2021-01-01', periods=n)})

# create data with vastly different ranges
for col in cols:
    start = np.random.choice([1, 10, 100, 1000, 100000])
    s = np.random.normal(loc=0, scale=0.01*start, size=n)
    df[col] = start + s.cumsum()

# melt data columns from wide to long
dfm = df.melt("Date")

# make the plot
fig = px.line(
    data_frame=dfm,
    x = 'Date',
    y = 'value',
    facet_col = 'variable',
    facet_col_wrap=6,
    facet_col_spacing=0.05,
    facet_row_spacing=0.035,
    height = 1000,
    width = 1000,
    title = 'Value vs. Date',
    labels = {
        'Date': '',
        'value': '',
        'variable': ''
    }
)

# ensure that each chart has its own y rage and tick labels
fig.update_yaxes(matches=None, showticklabels=True, visible=True)

fig.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


ves*_*and 5

这个答案有五个部分:

  1. 隐藏子情节标题(虽然不是 100% 确定你想这样做......)
  2. 使用隐藏 y 轴刻度值 fig.layout[axis].tickfont = dict(color = 'rgba(0,0,0,0)')
  3. 使用设置单轴标签 go.layout.Annotation(xref="paper", yref="paper")
  4. 情节图
  5. 最后完成代码片段

这里的一个非常重要的收获是,您可以px使用plotly.graph_object引用来编辑由函数生成的任何元素,例如go.layout.XAxis.


1.隐藏子情节标题

如果您对设置 的方式感到满意,则fig可以包括

for anno in fig['layout']['annotations']:
    anno['text']=''
    
fig.show()
Run Code Online (Sandbox Code Playgroud)

2.隐藏yaxis文本

您可以在循环中使用以下内容将 yaxis tickfont 设置为透明

fig.layout[axis].tickfont = dict(color = 'rgba(0,0,0,0)')
Run Code Online (Sandbox Code Playgroud)

该确切的行包含在下面的代码段中,它还删除了每个子图的 y 轴标题。

3. 单轴标签

轴标签和包容的单一标签的去除需要更多的工作,但这里有一个非常灵活的设置是不正是你需要什么,更多的,如果你想以任何方式编辑您的新标签:

# hide subplot y-axis titles and x-axis titles
for axis in fig.layout:
    if type(fig.layout[axis]) == go.layout.YAxis:
        fig.layout[axis].title.text = ''
    if type(fig.layout[axis]) == go.layout.XAxis:
        fig.layout[axis].title.text = ''
        
# keep all other annotations and add single y-axis and x-axis title:
fig.update_layout(
    # keep the original annotations and add a list of new annotations:
    annotations = list(fig.layout.annotations) + 
    [go.layout.Annotation(
            x=-0.07,
            y=0.5,
            font=dict(
                size=16, color = 'blue'
            ),
            showarrow=False,
            text="single y-axis title",
            textangle=-90,
            xref="paper",
            yref="paper"
        )
    ] +
    [go.layout.Annotation(
            x=0.5,
            y=-0.08,
            font=dict(
                size=16, color = 'blue'
            ),
            showarrow=False,
            text="Dates",
            textangle=-0,
            xref="paper",
            yref="paper"
        )
    ]
)

fig.show()
Run Code Online (Sandbox Code Playgroud)

4. 情节

在此处输入图片说明

5.完整代码:

import pandas as pd
import numpy as np
import plotly.express as px
import string
import plotly.graph_objects as go

# create a dataframe
cols = list(string.ascii_letters)
cols[0]='zzz'
n = 50

df = pd.DataFrame({'Date': pd.date_range('2021-01-01', periods=n)})

# create data with vastly different ranges
for col in cols:
    start = np.random.choice([1, 10, 100, 1000, 100000])
    s = np.random.normal(loc=0, scale=0.01*start, size=n)
    df[col] = start + s.cumsum()

# melt data columns from wide to long
dfm = df.melt("Date")

fig = px.line(
    data_frame=dfm,
    x = 'Date',
    y = 'value',
    facet_col = 'variable',
    facet_col_wrap=6,
    #facet_col_spacing=0.05,
    #facet_row_spacing=0.035,
    height = 1000,
    width = 1000,
    title = 'Value vs. Date'
)

fig.update_yaxes(matches=None, showticklabels=True, visible=True)
fig.update_annotations(font=dict(size=16))
fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))

# subplot titles
for anno in fig['layout']['annotations']:
    anno['text']=''

# hide subplot y-axis titles and x-axis titles
for axis in fig.layout:
    if type(fig.layout[axis]) == go.layout.YAxis:
        fig.layout[axis].title.text = ''
    if type(fig.layout[axis]) == go.layout.XAxis:
        fig.layout[axis].title.text = ''
        
# keep all other annotations and add single y-axis and x-axis title:
fig.update_layout(
    # keep the original annotations and add a list of new annotations:
    annotations = list(fig.layout.annotations) + 
    [go.layout.Annotation(
            x=-0.07,
            y=0.5,
            font=dict(
                size=16, color = 'blue'
            ),
            showarrow=False,
            text="single y-axis title",
            textangle=-90,
            xref="paper",
            yref="paper"
        )
    ] +
    [go.layout.Annotation(
            x=0.5,
            y=-0.08,
            font=dict(
                size=16, color = 'blue'
            ),
            showarrow=False,
            text="Dates",
            textangle=-0,
            xref="paper",
            yref="paper"
        )
    ]
)


fig.show()
Run Code Online (Sandbox Code Playgroud)