如何调整我的 Plotly 条高度并仅显示条的边缘(在子图中)?

2022-01-21 00:00:00 python plotly plotly-python

问题描述

这是我第一次涉足 Plotly.与 matplotlib 和散景相比,我喜欢它的易用性.然而,我被困在一些关于如何美化我的情节的基本问题上.首先,这是下面的代码(功能齐全,只需复制和粘贴!):

this is my first foray into Plotly. I love the ease of use compared to matplotlib and bokeh. However I'm stuck on some basic questions on how to beautify my plot. First, this is the code below (its fully functional, just copy and paste!):

import plotly.express as px
from plotly.subplots import make_subplots
import plotly as py
import pandas as pd
from plotly import tools

d = {'Mkt_cd': ['Mkt1','Mkt2','Mkt3','Mkt4','Mkt5','Mkt1','Mkt2','Mkt3','Mkt4','Mkt5'],
       'Category': ['Apple','Orange','Grape','Mango','Orange','Mango','Apple','Grape','Apple','Orange'],
           'CategoryKey': ['Mkt1Apple','Mkt2Orange','Mkt3Grape','Mkt4Mango','Mkt5Orange','Mkt1Mango','Mkt2Apple','Mkt3Grape','Mkt4Apple','Mkt5Orange'],
            'Current': [15,9,20,10,20,8,10,21,18,14],
           'Goal': [50,35,21,44,20,24,14,29,28,19]
     }
dataset  = pd.DataFrame(d)

grouped = dataset.groupby('Category', as_index=False).sum()
data = grouped.to_dict(orient='list')
v_cat = grouped['Category'].tolist()
v_current = grouped['Current']
v_goal = grouped['Goal']
fig1 = px.bar(dataset, x = v_current, y = v_cat, orientation = 'h',
              color_discrete_sequence = ["#ff0000"],height=10)
fig2 = px.bar(dataset, x = v_goal, y = v_cat, orientation = 'h',height=15)

trace1 = fig1['data'][0]
trace2 = fig2['data'][0]
fig = make_subplots(rows = 1, cols = 1, shared_xaxes=True, shared_yaxes=True)
fig.add_trace(trace2, 1, 1)
fig.add_trace(trace1, 1, 1)
fig.update_layout(barmode = 'overlay')
fig.show()

这是输出:

问题1:如何使v_current(红色条所示)的宽度变小?如中,它的高度应该更小,因为这是一个水平条.我将 trace1 的高度添加为 10,将 trace2 的高度添加为 15,但它们仍然显示在相同的高度.

Question1: how do I make the width of v_current (shown in red bar) smaller? As in, it should be smaller in height since this is a horizontal bar. I added the height as 10 for trace1 and 15 for trace2, but they are still showing at the same heights.

问题2:有没有办法让 v_goal(以蓝色条显示)只显示它的右边缘,而不是填充条?像这样的东西:

Question2: Is there a way to make the v_goal (shown in blue bar) only show it's right edge, instead of a filled out bar? Something like this:

如果您注意到,我还在每个类别下添加了一行.有没有一种快速的方法来添加它?不是破坏交易,只是奖金.我正在尝试做的其他事情是添加动画等,但那是其他时间!

If you noticed, I also added a line under each of the category. Is there a quick way to add this as well? Not a deal breaker, just a bonus. Other things I'm trying to do is add animation, etc but that's for some other time!

提前感谢您的回答!


解决方案

运行 plotly.express 将返回一个 plotly.graph_objs._figure.Figure 对象.plotly.graph_objects 运行 go.Figure() 以及例如 go.Bar() 也是如此.所以在使用 plotly express 构建图形后,您可以通过直接对图形的引用添加线条或轨迹,例如:

Running plotly.express wil return a plotly.graph_objs._figure.Figure object. The same goes for plotly.graph_objects running go.Figure() together with, for example, go.Bar(). So after building a figure using plotly express, you can add lines or traces through references directly to the figure, like:

fig['data'][0].width = 0.4

这正是您设置条形宽度所需的.您可以轻松地将其与 plotly express 结合使用:

Which is exactly what you need to set the width of your bars. And you can easily use this in combination with plotly express:

fig = px.bar(grouped, y='Category', x = ['Current'],
             orientation = 'h', barmode='overlay', opacity = 1,
             color_discrete_sequence = px.colors.qualitative.Plotly[1:])
fig['data'][0].width = 0.4

情节 1

为了获得指示目标级别的条形或形状,您可以使用 DerekO 描述的方法,也可以使用:

In order to get the bars or shapes to indicate the goal levels, you can use the approach described by DerekO, or you can use:

for i, g in enumerate(grouped.Goal):
    fig.add_shape(type="rect",
                    x0=g+1, y0=grouped.Category[i], x1=g, y1=grouped.Category[i],
                    line=dict(color='#636EFA', width = 28))

完整代码:

import plotly.express as px
from plotly.subplots import make_subplots
import plotly as py
import pandas as pd
from plotly import tools

d = {'Mkt_cd': ['Mkt1','Mkt2','Mkt3','Mkt4','Mkt5','Mkt1','Mkt2','Mkt3','Mkt4','Mkt5'],
       'Category': ['Apple','Orange','Grape','Mango','Orange','Mango','Apple','Grape','Apple','Orange'],
           'CategoryKey': ['Mkt1Apple','Mkt2Orange','Mkt3Grape','Mkt4Mango','Mkt5Orange','Mkt1Mango','Mkt2Apple','Mkt3Grape','Mkt4Apple','Mkt5Orange'],
            'Current': [15,9,20,10,20,8,10,21,18,14],
           'Goal': [50,35,21,44,20,24,14,29,28,19]
     }
dataset  = pd.DataFrame(d)

grouped = dataset.groupby('Category', as_index=False).sum()

fig = px.bar(grouped, y='Category', x = ['Current'],
             orientation = 'h', barmode='overlay', opacity = 1,
             color_discrete_sequence = px.colors.qualitative.Plotly[1:])

fig['data'][0].width = 0.4
fig['data'][0].marker.line.width = 0

for i, g in enumerate(grouped.Goal):
    fig.add_shape(type="rect",
                    x0=g+1, y0=grouped.Category[i], x1=g, y1=grouped.Category[i],
                    line=dict(color='#636EFA', width = 28))
f = fig.full_figure_for_development(warn=False)
fig.show()

相关文章