Home > OS >  Mix histogram and line plots in plotly together
Mix histogram and line plots in plotly together

Time:12-29

Hi all and Happy Holidays!

I am trying to do a combined plot, using plotly, of an histogram and a line plot. I have a large pandas dataframe (shown only the first ten lines):

    Year    Selling_Price
0   8.0     4950.0
1   8.0     4070.0
2   16.0    1738.0
3   12.0    2475.0
4   15.0    1430.0
5   5.0     4840.0
6   15.0    1056.0
7   21.0    495.0
8   11.0    3850.0
9   9.0     2200.0
10  8.0     5500.0
11  17.0    1012.0
12  13.0    3080.0
14  13.0    1980.0
15  6.0     4400.0
16  6.0     8558.0
17  10.0    5500.0
18  20.0    1650.0
19  6.0     7480.0
20  11.0    1914.0

First I have plotted the distribution of the variable Year as follows:

import plotly.express as px

fig_1 = px.histogram(data, x="Year", marginal="box")
fig_1.show()

enter image description here

Then, I have plotted the Average Selling Price by year, using the following lines of code:

df_1 = pd.DataFrame(data.groupby('Year')['Selling_Price'].mean().sort_index(ascending=True))
df_1.rename(columns={'Selling_Price':'Average Selling Price'},inplace=True)
df_1['Year'] = df_1.index
df_1.reset_index(drop=True,inplace=True)
fig_1 = px.line(df_1, x="Year", y="Average Selling Price")
fig_1.show()

enter image description here

However, I want to have them combined into one column and two rows graph. I wrote the function:

def Plot_Continuous(df,column_group,target):
    # Copies the dataframe
    df = df.copy()
    df_1 = pd.DataFrame(df.groupby(column_group)[target].mean().sort_index(ascending=True))
    df_1.rename(columns={target:'Average Selling Price'},inplace=True)
    fig = make_subplots(rows=2, cols=1)
    fig.append_trace(px.histogram(df, x=column_group, marginal="box", hover_data=df.columns), row=1, col=1)
    fig.append_trace(px.line(df_1, x="Year", y="Average Selling Price"), row=2, col=1)
    fig.update_layout(height=800, width=1000)
    fig.show()  

but when I call it: Plot_Continuous(dataframe,'Year','Selling_Price'), I get the error message:

ValueError: 
    Invalid element(s) received for the 'data' property of 
        Invalid elements include: [Figure({
    'data': [{'alignmentgroup': 'True',
              'bingroup': 'x',
              'hovertemplate': 'Year=%{x}<br>count=%{y}<extra></extra>',
              'legendgroup': '',
              'marker': {'color': '#636efa', 'pattern': {'shape': ''}},
              'name': '',
              'offsetgroup': '',
              'orientation': 'v',
              'showlegend': False,
              'type': 'histogram',
              'x': array([ 8.,  8., 16., ...,  9., 15., 13.]),
              'xaxis': 'x',
              'yaxis': 'y'},.................

If I use go.Histogram and go.Line, then I get an error message with the marginal="box" parameter, which I would like to keep inside the plot, but not working if I leave it there.

How could I properly combine both plots as they are shown in the images above, one below the other?

Thanks in advance and Happy Holidays!

CodePudding user response:

The graphs consist of a histogram, a box plot, and a line graph, but we reused the graph data created by Express to create the graphs. The first histogram composition consists of a histogram and a boxplot. It is then rearranged into subplots of two rows and one column. Next, the line graph data is placed in the second row. What is needed here is to specify the graph specification for the subplot. Normally, we would use a graph type, but since this is a histogram and a line graph, we use xy. In addition, the second y-axis is enabled.

import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots

fig1 = px.histogram(df, x="Year", marginal="box")
fig2 = px.line(df_1, x="Year", y="Average Selling Price")
fig2.update_traces(line_color='red')

fig = make_subplots(rows=2, cols=1, specs=[[{'type': 'box'}], [{'type':'xy', 'secondary_y':True}]])

fig.add_trace(go.Box(fig1.data[1]), row=1, col=1)
fig.add_trace(go.Histogram(fig1.data[0]), row=2, col=1)
fig.add_trace(go.Scatter(fig2.data[0]), secondary_y=True, row=2, col=1)

fig.update_layout(yaxis=dict(domain=[0.8516, 1.0]),
                  yaxis2=dict(domain=[0.0, 0.8316], title_text='Count'),
                  yaxis3=dict(title_text='Average Selling Price'),
                  xaxis=dict(showticklabels=False),
                  xaxis2=dict(title_text='Year'),                  
                 )
fig.show()

enter image description here

  • Related