How to generate back to back chart in D3? - python

I am using Matplotlib for a back to back plot:
import numpy as np
import matplotlib.pyplot as plt
# create data
A = np.array([3,6,9,4,2,5])
B = np.array([2,8,1,9,7,3])
X = np.arange(6)
# plot the bars
plt.barh(X, A, align='center',
alpha=0.9, color = 'y')
plt.barh(X, -B, align='center',
alpha=0.6, color = 'c')
plt.yticks([0, 1, 2,3,4,5], ['A', 'B', 'C', 'D', 'E', 'F'])
plt.xticks([], [])
plt.show()
I am wondering how to generate d3 code using python?
Is Altair the right option?

Here is an example of generating a similar chart with Altair:
import pandas as pd
import altair as alt
df = pd.DataFrame({
"A": np.array([3,6,9,4,2,5]),
"B": np.array([2,8,1,9,7,3]),
"X": ['A', 'B', 'C', 'D', 'E', 'F'],
})
alt.Chart(df).transform_calculate(
A=-alt.datum.A
).transform_fold(
["A", "B"], as_=["key", "value"]
).mark_bar().encode(
x=alt.X("value:Q", axis=None),
y='X:N',
color="key:N"
).properties(
width=300,
height=200
)

Related

Plotly: How to avoid grouping of x and y categories using go.Heatmap?

Hi I want to make a Heatmap using Plotly, like this:
https://drive.google.com/uc?export=view&id=1594s6eo3VfxRXrS-2asrGeiFAT-08G-w
The problem is that Plotly indexes x columns. The same column names cause a problem in my code.
https://drive.google.com/uc?export=view&id=1_KqOzzoikoKHd8TMNP20T4hDfy03KD8G
I want to make my x-axis columns display “T,G,G,G,A”, but they currently display as “T,G,A”.
How do I make my x-column display “T,G,G,G,A”?
My code is as follows:
import plotly.graph_objects as go
import numpy as np
z = np.random.rand(4,5)
y = ['A','C','G','T']
x = ['T', 'G', 'G', 'G', 'A']
fig = go.Figure(
data = go.Heatmap(z=z, y=y,x=x)
)
fig.show()
Remove y=y and x=x from go.Heatmap, specify tickmode, tickvals and ticktext like this:
fig.update_yaxes(tickmode = 'array',
tickvals = np.arange(0, len(y)),
ticktext= y)
And you'll get:
Complete code:
import plotly.graph_objects as go
import numpy as np
z = np.random.rand(4,5)
y = ['A','C','G','T']
x = ['T', 'G', 'G', 'G', 'A']
fig = go.Figure(
data = go.Heatmap(z=z)
)
fig.update_yaxes(tickmode = 'array',
tickvals = np.arange(0, len(y)),
ticktext= y)
fig.update_xaxes(tickmode = 'array',
tickvals = np.arange(0, len(x)),
ticktext= x,
side = 'top')
If anything is unclear then let me know and we can get into the details.

Matplotlib Hover Text

I created this tree map using Matplotlib and Squarify. Is there a way to display information about each axes when the mouse hovers over the axis?
The mplcursors library can be used to create custom annotations while hovering. Here is an example with a tree map:
import matplotlib.pyplot as plt
import matplotlib as mpl
import squarify
import mplcursors
sizes = [5, 20, 30, 25, 10, 12]
sumsizes = sum(sizes)
labels = ['A', 'B', 'C', 'D', 'E', 'F']
cmap = plt.cm.get_cmap('Greens')
norm = plt.Normalize(vmin=min(sizes), vmax=max(sizes))
colors = [cmap(norm(s)) for s in sizes]
squarify.plot(sizes=sizes, label=labels, color=colors)
plt.colorbar(plt.cm.ScalarMappable(cmap=cmap, norm=norm))
cursor = mplcursors.cursor(hover=True)
cursor.connect("add", lambda sel: sel.annotation.set_text(
f"ID:{sel.target.index} '{labels[sel.target.index]}'\nSize:{sizes[sel.target.index]} ({sizes[sel.target.index] * 100.0 / sumsizes:.1f} %)"))
plt.show()

Missing labels in matplotlib pie chart

I try to plot a pie chart using Python 3 Matplotlib v2.2.2-4build1 on Ubuntu 18.10. Everything seems to be ok except labels - they are missing. Tried to add it according to official documentation (https://matplotlib.org/api/_as_gen/matplotlib.pyplot.pie.html), tried to use an example from the web (https://pythonspot.com/matplotlib-pie-chart/) - same result, no labels.
Here is a simplified version of my code:
import numpy as np
import matplotlib.pyplot as plt
import sys
headers = ['a', 'b', 'c', 'd', 'e']
values = [5, 4, 3, 2, 1]
sum = sum(values)
labels = []
for v in values:
labels.append('{:.1f}%'.format(100 * v / sum))
fig, ax = plt.subplots(figsize=(6, 3), subplot_kw=dict(aspect="equal"))
wedges, texts = ax.pie(values, labels=labels, textprops=dict(color="w"))
plt.show()
Here is what I see - no labels:
Tried to use a tuple instead of a list - same thing.
Could anybody help me?
You might want to make the color of your labels non-white on a white background :)
Also using sum as a variable name overwrites the function, so your're better off choosing something else.
import numpy as np
import matplotlib.pyplot as plt
import sys
headers = ['a', 'b', 'c', 'd', 'e']
values = [5, 4, 3, 2, 1]
sumT = sum(values)
labels = []
for v in values:
labels.append('{:.1f}%'.format(100 * v / sumT))
fig, ax = plt.subplots(figsize=(6, 3), subplot_kw=dict(aspect="equal"))
wedges, texts = ax.pie(values, labels=labels, textprops=dict(color="k"))
plt.show()
Or if you want the labels to be inside:
import numpy as np
import matplotlib.pyplot as plt
import sys
def func(pct, allvals):
absolute = int(pct/100.*sum(allvals))
return "{:.1f}%)".format(pct)
headers = ['a', 'b', 'c', 'd', 'e']
values = [5, 4, 3, 2, 1]
sumT = sum(values)
labels = []
for v in values:
labels.append('{:.1f}%'.format(100 * v / sumT))
fig, ax = plt.subplots(figsize=(6, 3), subplot_kw=dict(aspect="equal"))
wedges, texts = ax.pie(values, autopct=lambda pct: func(pct,
values), textprops=dict(color="w"))
plt.show()
import numpy as np
import matplotlib.pyplot as plt
import sys
headers = ['a', 'b', 'c', 'd', 'e']
values = [5, 4, 3, 2, 1]
colors=['yellow','blue','red','pink','green']
plt.pie(values,labels=headers,
colors=colors,autopct='%1.2f%%',
shadow=True,startangle=90)
plt.title('pie chart')
plt.show()
Adding the plt.legend() statement before the plt.show() will do the job.
import numpy as np
import matplotlib.pyplot as plt
import sys
headers = ['a', 'b', 'c', 'd', 'e']
values = [5, 4, 3, 2, 1]
labels = []
for v in values:
labels.append('{:.1f}%'.format(100 * v / sum))
fig, ax = plt.subplots(figsize=(6, 3), subplot_kw=dict(aspect="equal"))
wedges, texts = ax.pie(values, labels=labels, textprops=dict(color="w"))
plt.legend()
plt.show()

Separate two groups of bars in matplotlib

Do you know if it is possible to separate the bars into two groups of different sizes, but maintaining both in the same plot? I have this code:
import matplotlib.pyplot as plt; plt.rcdefaults()
import numpy as np
import matplotlib.pyplot as plt
objects = ('A', 'B', 'C', 'D', 'E', 'F', 'G')
y_pos = np.arange(len(objects))
performance = [15.3, 25.8, 37.1, 50.0, 15.0, 18.5, 28.9]
plt.bar(y_pos, performance, align='center', alpha=0.5)
plt.xticks(y_pos, objects)
plt.ylabel('Reduction Error')
plt.title("")
plt.show()
And I would like to have A and B close together, then some space, and then all the other bars.
I found this issue Function to create grouped bar plot, but I would like to keep each name under the bar and not group them as in the example.
Thank you for your help!
If I understood you correctly, you can do in this way:
objects = ('A', 'B', 'C', 'D', 'E', 'F', 'G')
x = [1,1.8,5,6,7,8,9]
performance = [15.3, 25.8, 37.1, 50.0, 15.0, 18.5, 28.9]
plt.bar(x, performance, align='center', alpha=0.5)
plt.xticks(x, objects)
plt.ylabel('Reduction Error')
plt.title("")
plt.show()
Or use 2 instead of 1.8 in x to have some space between A and B

Python: making column/row labels of matplotlib table bold

I'm trying to figure out how to bold the column and row labels for a matplotlib table I'm making.
I've gone through the different table properties, and I can figure out how to style the individual cells, but not the actual columns or row labels.
Further, I'm not able to find out how to bold anything.. just font size, actual font, and color.
Any help?
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
fig, axs =plt.subplots(figsize = (10,6))
clust_data = np.random.random((10,3))
collabel=("col 1", "col 2", "col 3")
axs.axis('tight')
axs.axis('off')
df = pd.DataFrame(np.random.randn(10, 4),
columns=['a','b','c','d'],
index = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])
table = axs.table(cellText=df.values, colLabels = df.columns, rowLabels = df.index, loc='center')
plt.show()
EDIT:
Figured it out, though it's kind of clunky. You can find the columns/row labels in the "celld" property. You can then set it to bold using .set_text_props(fontproperties = FontProperties(weight = 'bold'). i.e.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import pandas as pd
fig, axs =plt.subplots(figsize = (10,6))
clust_data = np.random.random((10,3))
collabel=("col 1", "col 2", "col 3")
axs.axis('tight')
axs.axis('off')
df = pd.DataFrame(np.random.randn(10, 4),
columns=['a','b','c','d'],
index = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'])
table = axs.table(cellText=df.values, colLabels = df.columns, rowLabels = df.index, loc='center')
P = []
for key, cell in table.get_celld().items():
row, col = key
P.append(cell)
for x in P[40:]:
x.set_text_props(fontproperties=FontProperties(weight='bold'))
plt.show()
A slightly better method, following the documentation:
from matplotlib.font_manager import FontProperties
for (row, col), cell in table.get_celld().items():
if (row == 0) or (col == -1):
cell.set_text_props(fontproperties=FontProperties(weight='bold'))

Categories