Plotly:如何在 plotly express 动画中指定分类 x 轴元素?

2022-01-21 00:00:00 python python-3.x plotly plotly-python

问题描述

我有以下数据.

我正在使用滑块,这样我就可以在不同的日期之间滑动(请参阅下图以了解滑块是什么情况).现在,由于我的类别可能在日期之间发生变化,我想用 A、B、C、E、F 初始化我的 x 轴范围,无论我的日期是什么.所以有时我会在一个类别中没有数据点,但这对我来说并不重要.

那么如何初始化我的x轴范围,让我的数据点适应初始化后的x轴呢?

我正在使用 python3 和 plotly express.

这是我现在的代码:

data.columns = ['price', 'category', 'date']data = data.sort_values(by=['date', 'price'])fig = px.scatter(data, x = "category", y = "price", animation_frame="date")fig.update_layout(yaxis_title=价格(欧元)",)fig['layout']['updatemenus'][0]['pad']['t'] = 180fig['layout']['slider'][0]['pad']['t'] = 200fig.write_html("/home/**/Desktop/1.html", auto_play=True)

我希望我已经足够清楚了.如果您需要任何额外信息,请告诉我.欢迎任何想法或提示:)

解决方案

答案:

确保所有动画帧的所有类别都显示在 x 轴上的唯一方法是确保它们出现在第一个 Date = X 中.因此,您实际上无法修复图中本身的 x 轴范围.您必须通过数据源的表示来完成.

详情:

<块引用>

所以有时我会在某个类别中没有数据点,但这对我来说并不重要.

也许不是,但 对 plotly.express 很重要.特别是如果您没有数据";意味着您的数据集中没有所有日期的所有类别的记录.你看,plotly 似乎将 x 轴值设置为它在 Date = X 的第一个唯一值中找到的类别,即 A、B、C.但别担心,我们也会处理的.让我们使用稍微改动过的数据截图版本(下一次,这样做).我添加了实际日期而不是 X, Y 并稍微缩小了数字的范围,因为您的特定数据会使动画有点混乱.

如果我们使用这样的动画方法:

fig = px.scatter(df1, x="Category", y="Price", animation_frame="Date",颜色=类别",范围_y=[0,20])

...你会得到两个动画帧:

情节 1,第 1 帧

情节 1,第 2 帧

现在,让我们使用一种方法来确保所有日期都显示所有类别,您可以在帖子中找到

情节 2,第 2 帧

我希望这就是您想要的.如果没有,请不要犹豫,让我知道!如果您删除 df1.fillna(0) 部分,您会得到稍微不同的结果.但我会让你自己来处理

中的所有可用选项

完整代码:

将 pandas 导入为 pd将 plotly.express 导入为 pxdf = pd.DataFrame({'日期': {0: '24.08.2020',1:2020 年 8 月 24 日",2:2020 年 8 月 24 日",3:2020 年 8 月 25 日",4:2020 年 8 月 25 日",5: '25.08.2020'},类别":{0:A",1:B",2:C",3:C",4:E",5:F"},价格":{0:1、1:2、2:3、3:3、4:10、5:13}})# 确保所有类别变量都表示为# 所有日期,即使不是所有变量都有值.df['key']=df.groupby(['Date','Category']).cumcount()df1 = pd.pivot_table(df,index='Date',columns=['key','Category'],values='Price')df1 = df1.stack(level=[0,1],dropna=False).to_frame('Price').reset_index()df1 = df1[df1.key.eq(0) |df1['价格'].notna()]df1=df1.fillna(0)# ploty express 动画fig = px.scatter(df1, x="Category", y="Price", animation_frame="Date",颜色=类别",范围_y=[0,20])# 一些额外的设置.fig.update_layout(transition = {'duration': 20000})图.show()

I have the following data.

I am using a slider, so that I can slide through the different dates (please see the picture below to see what a slider is in case). Now, as my category may change between the dates I want to initialize my x-axis range with A,B,C,E,F no matter what my date is. So sometimes I will have no data points in a category but this does not matter to me.

So how can initialize my x-axis range and make my data points adapt to the initialized x-axis?

I am using python3 and plotly express.

This is my code for now :

data.columns = ['price', 'category', 'date']
    data = data.sort_values(by=['date', 'price'])
    fig = px.scatter(data, x = "category", y = "price", animation_frame="date")
    fig.update_layout(
        yaxis_title="Price (€)",
    )
    fig['layout']['updatemenus'][0]['pad']['t'] = 180
    fig['layout']['sliders'][0]['pad']['t'] = 200
    fig.write_html("/home/**/Desktop/1.html", auto_play=True)

Ihope I was clear enough. Please let me know if you need any extra information. Any ideas or tips is welcome :)

解决方案

The answer:

The only way you can make sure that all categories are represented on the x-axis for all animation frames is to make sure they appear in the first Date = X. So you can't actually fix the x-axis ranges in the figure itself. You'll have to do it through your representation of the data source.

The details:

So sometimes I will have no data points in a category but this does not matter to me.

Maybe not, but it will matter to plotly.express. Particularly if you by "have no data" mean that you do not have records for all categories in your dataset for all dates. You see, plotly seems to set the x-axis values to the categories it finds in the first unique values for Date = X which is A, B ,C. But don't worry, we'll handle that too. Let's use a slightly altered version of your data screenshot (next time, do this). I've added actual dates instead of X, Y and reduced the range of the numbers a bit since your particular data messes up the animation a bit.

If we use an animation approach like this:

fig = px.scatter(df1, x="Category", y="Price", animation_frame="Date",
                  color="Category", range_y=[0,20])

... you'll get two animation frames:

Plot 1, frame 1

Plot 1, frame 2

Now, lets use an approach to make sure alle categories are represented for all dates as you can find in the post Pandas: How to include all columns for all rows although value is missing in a dataframe with a long format?

Now you'll get:

Plot 2, frame 1

Plot 2, frame 2

I hope this is what you were looking for. Don't hesitate to let me know if not! You'll get a slightly different result if you drop the df1.fillna(0) part. But I'll leave it up to you to mess around with all available options in the

Complete code:

import pandas as pd
import plotly.express as px

df = pd.DataFrame({'Date': {0: '24.08.2020',
                              1: '24.08.2020',
                              2: '24.08.2020',
                              3: '25.08.2020',
                              4: '25.08.2020',
                              5: '25.08.2020'},
                             'Category': {0: 'A', 1: 'B', 2: 'C', 3: 'C', 4: 'E', 5: 'F'},
                             'Price': {0: 1, 1: 2, 2: 3, 3: 3, 4: 10, 5: 13}})

# make sure that all category variables are represented for
# all dates even though not all variables have values.
df['key']=df.groupby(['Date','Category']).cumcount()
df1 = pd.pivot_table(df,index='Date',columns=['key','Category'],values='Price')
df1 = df1.stack(level=[0,1],dropna=False).to_frame('Price').reset_index()
df1 = df1[df1.key.eq(0) | df1['Price'].notna()]
df1=df1.fillna(0)

# ploty express animation
fig = px.scatter(df1, x="Category", y="Price", animation_frame="Date",
                  color="Category", range_y=[0,20])

# some extra settings.
fig.update_layout(transition = {'duration': 20000})


fig.show()

相关文章