How to overlay multiple customized pie charts in Plotly? - python

I'm trying to reproduce a chart that I made in Python using matplotlib using plotly as I would like my chart to have more interactivity and potentially other features that plotly can offer in combination with Dash.
I want to achieve a couple of things so I will ask the following questions:
Is it possible in Plotly to overlay multiple pie charts, one on top of each other but of different sizes?
How can I adjust the radius in Plotly? I know this option is available in matplotlib but I haven't found that in Plotly.
Is there a way to control each slice individually such as adjust the radius to make the slice longer, adjust opacity but an individual slice? I found an example with hiding a particular slice but this one changes the pie chart completely, I would like for the slice that was turned off/made invisible to stay there, pie chart shouldn't change its composition. https://community.plotly.com/t/is-there-a-way-to-hide-some-slices-by-default-in-a-pie-chart/884
Is there a way to use continuous colors/colormap in a pie chart? From what I've read the documentation only mentions the option to use discrete.
Below I attempted to make a smaller pie chart on top of another using some example from the documentation but I failed to do so. Btw, I'm using some custom data.
import plotly.graph_objs as go
df = pd.read_csv('data.csv', index_col=0)
# change index to string
df.index = df.index.map(str)
names = ['Null', 'Pred=-1', 'Pred=0', 'Other', 'R_min'] + df.index[5:].tolist()
trace0 = go.Pie(
values=df['sum_cnt'], labels=names, opacity=0.5)
trace1 = go.Pie(
values=df['sum_cnt'], marker_colors=px.colors.sequential.Sunset,
textinfo='none',
hoverinfo='none',
domain={'x': [0.33, 0.66], 'y': [0.0, 0.6]})
data = [trace0,trace1]
layout = go.Layout(title="Chart",
)
fig = go.Figure(data=data, layout=layout, layout_showlegend=False)
fig.show()

Related

Gibberish / malformed negative y-axis values in plotly charts in python

Im trying to plot a bar plot in plotly that is representing net-gains (will have positive and negative bar values). But somewhat the negative values in the y-axis are being represented in gibberish. I tried several things, including using update_layout function, but nothing seems to work. Im using the make_subplots function because i want to plot multiple viz on one figure.
Im using databricks for this code.
Attaching my code and viz output:
net_gains = pd.DataFrame()
net_gains["general_net_gain"] = [-2,2,-1,2]
fig = plotly.subplots.make_subplots(rows=1, cols=1)
fig.add_bar(x=net_gains.index, y=net_gains["general_net_gain"], row=1, col=1)
fig.update_layout(height=400,width=500,showlegend=True)

display number on top or bottom of a candlestick chart with plotly or other charting libraries

Assume my data look like this:
With open/close/high/low/ I want to display a normal candlestick, but I also want to add the number in annotation column to top or bottom of the candlestick chart (like chart below), can anyone help me potentially ways how to achieve it. Thank you!
I have tried mplfinance, but looking is not that great.
There are several ways to annotate, but in the case of this question it is easiest to use the text mode for scatter plots. After creating the candlestick, add a scatter plot. To link the position to be annotated in the string to the candlestick, the opening and closing prices are compared, with the price corresponding to the annotation position as the value. In addition, since all text annotation positions are set to "top center," an offset position is set and calculated. This could be done by having a list of annotation positions for every line. However, since there is no clear rule regarding the annotation position, we have set it to the candlestick reference.
offset = 0.004
df['txt_position'] = np.where(df['Open'] >= df['Close'], df['Open'], df['Low'] - offset)
import pandas as pd
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(
go.Candlestick(
x=df['Date'],
open=df['Open'],
high=df['High'],
low=df['Low'],
close=df['Close'],
name='candlestick'
)
)
fig.add_trace(go.Scatter(x=df['Date'],
y=df['txt_position'],
mode='text',
text=df['Annotation'],
textposition='top center',
name='annotation')
)
fig.update_layout(xaxis_rangeslider_visible=False)
fig.show()

Size legend for plotly express scatterplot in Python

Here is a Plotly Express scatterplot with marker color, size and symbol representing different fields in the data frame. There is a legend for symbol and a colorbar for color, but there is nothing to indicate what marker size represents.
Is it possible to display a "size" legend? In the legend I'm hoping to show some example marker sizes and their respective values.
A similar question was asked for R and I'm hoping for a similar results in Python. I've tried adding markers using fig.add_trace(), and this would work, except I don't know how to make the sizes equal.
import pandas as pd
import plotly.express as px
import random
# create data frame
df = pd.DataFrame({
'X':list(range(1,11,1)),
'Y':list(range(1,11,1)),
'Symbol':['Yes']*5+['No']*5,
'Color':list(range(1,11,1)),
'Size':random.sample(range(10,150), 10)
})
# create scatterplot
fig = px.scatter(df, y='Y', x='X',color='Color',symbol='Symbol',size='Size')
# move legend
fig.update_layout(legend=dict(y=1, x=0.1))
fig.show()
Scatterplot Image:
Thank you
You can not achieve this goal, if you use a metric scale/data like in your range. Plotly will try to always interpret it like metric, even if it seems/is discrete in the output. So your data has to be a factor like in R, as you are showing groups. One possible solution could be to use a list comp. and convert everything to a str. I did it in two steps so you can follow:
import pandas as pd
import plotly.express as px
import random
check = sorted(random.sample(range(10,150), 10))
check = [str(num) for num in check]
# create data frame
df = pd.DataFrame({
'X':list(range(1,11,1)),
'Y':list(range(1,11,1)),
'Symbol':['Yes']*5+['No']*5,
'Color':check,
'Size':list(range(1,11,1))
})
# create scatterplot
fig = px.scatter(df, y='Y', x='X',color='Color',symbol='Symbol',size='Size')
# move legend
fig.update_layout(legend=dict(y=1, x=0.1))
fig.show()
That gives:
Keep in mind, that you also get the symbol label, as you now have TWO groups!
Maybe you want to sort the values in the list before converting to string!
Like in this picture (added it to the code above)
UPDATE
Hey There,
yes, but as far as I know, only in matplotlib, and it is a little bit hacky, as you simulate scatter plots. I can only show you a modified example from matplotlib, but maybe it helps you so you can fiddle it out by yourself:
from numpy.random import randn
z = randn(10)
red_dot, = plt.plot(z, "ro", markersize=5)
red_dot_other, = plt.plot(z*2, "ro", markersize=20)
plt.legend([red_dot, red_dot_other], ["Yes", "No"], markerscale=0.5)
That gives:
As you can see you are working with two different plots, to be exact one plot for each size legend. In the legend these plots are merged together. Legendsize is further steered through markerscale and it is linked to markersize of each plot. And because we have two plots with TWO different markersizes, we can create a plot with different markersizes in the legend. markerscale is normally a value between 0 and 1 but you can also do 150% thus 1.5.
You can achieve this through fiddling around with the legend handler in matplotlib see here:
https://matplotlib.org/stable/tutorials/intermediate/legend_guide.html

Create a horizontal waterfall chart with python matplotlib

I am trying to create a waterfall chart, which is like a bar chart, except that each bar starts at the end of its neighboring bars, at the end or beginning, so you have the total, and can see how it breaks down.
I am trying to create this chart in python, but there are no direct charts in matplot.lib called waterfall.
I found code for a vertical waterfall, but I could not transform it to horizontal.
How can I transform a barh matplot chart, for example, to a horizontal waterfall?
I want to create a HORIZONTAL waterfall.
For example, I am trying to make each bar in barh chart in matplotlib start at end of other, but I do not think I am approaching the problem the right way, because I have no results so far.
It should look like this:
Code to create the plot:
my_plot = trans.plot(
kind='barh',
stacked=True,
bottom=blank,legend=None,
figsize=(10, 5)
)
How do I separate the bars?
EDIT
I have found this ready to use python package, but it doesn't work with dataframes, so I cannot use it.
import waterfall_chart
from matplotlib import transforms
a = ['sales','returns','credit fees','rebates','late charges','shipping']
b = [10,-30,-7.5,-25,95,-7]
my_plot = waterfall_chart.plot(a, b, rotation_value=30, sorted_value=True, threshold=0.2,
formatting="$ {:,.1f}", net_label="end result", other_label="misc",
Title="chart", x_lab="X", y_lab="money", blue_color="blue",
green_color="#95ff24", red_color="r")
rot = transforms.Affine2D().rotate_deg(90)
my_plot.show()
I also found this tutorial, with code, for a vertical waterfall chart.
https://pbpython.com/waterfall-chart.html.
It works great, but I didn't manage to reproduce the same thing for a horizontal waterfall.

How to plot 3D Bar chart/ Pie Chart/ Donut using Plotly

I have found code to make bar charts and pie charts in plotly also other 3D plots.
A simple bar chart works like this:
from plotly.offline import plot
from plotly.graph_objs import *
trace1 = Bar(
x=['cats', 'dogs', 'monkeys'],
y=[20, 14, 23]
)
data = Data([trace1])
plot(data)
Is there any option available in plotly to plot this bar graph in 3D layout. Also for pie chart/donut also?
Have a look at the official documentation:
https://plot.ly/python/3d-charts/
As this should be a list of all available 3D Charts in plot.ly:
No, it seems there is currently no option for 3D Bar/Pie/Donut.
See also: https://community.plot.ly/t/will-there-be-3d-bar-charts-in-the-future/1045/2
Bar/Pie/Donut are two-dimensional by nature, making them 3D would provide no additional value (apart from cosmetics)
As suggested in the link above, you could try using 3D filled line plots.
Though I doubt that the additional complexity required to get the desired result is worth it.
Still, 3D bar charts haven't been implemented in Plotly. There is a variant of 3D bar chart plotting function at https://github.com/buran21/barchart3d-plotly, intended for drawing of 1D labelled data. An example:
import plotly.data as pdata
from barchart3d import barchart3d
df = pdata.gapminder()
df = df[df['year'] == 2007].sort_values(by='pop', ascending=False).head(10)
fig = barchart3d(
df['country'].to_list(), (df['pop']/1e06).round(1).to_list(),
'Top 10 most populous countries in 2007 [Gapminder]', 'Population, mln',
colorscale='Bluered', opacity=0.6, flatshading=True)
fig.show()

Categories