4

This is a typical energy ranking that is used in a few published papers and I am struggling to reproduce one for my data using Python (anything matplotlib, sns etc.). I have my data constructed in Pandas dataframe like below:

System  Color_id  Data1  Data2
Form I     1      0.0    0.6
Form II    2      0.8    0.0
Form III   3      2.1    2.7
Form IV    4      2.2    0.3
Form V     5      1.7    1.2

I added "Color_id" column to enable specific_column_values coloring as in matplotlib and I think I am half-way using simply plt.scatter. What I am struggling mostly is plotting elongated lines instead of typical markers, and how to automatically connect those dash lines between similar systems across different data? Any help or suggestions is much appreciated.

Energy Ranking Plots

Community
  • 1
  • 1
TwinPenguins
  • 475
  • 9
  • 17
  • maybe it it help : http://stackoverflow.com/questions/20130227/matplotlib-connect-scatterplot-points-with-line-python – Dadep Mar 29 '17 at 13:39
  • markers are rendered unicode characters, so there's quite a selection, but they can't easily be modified. giving width between where the connecting dashed lines attach requires two points anyway, so I would recommend creating a helper function that generates line artists for the solid and dashed lines separately – Aaron Mar 29 '17 at 13:43

2 Answers2

2

I implemented an example of what I suggested in the comments. This doesn't automatically scale the axes (I hardcoded it), or add the tick labels, but those are all things you should be able to find on other questions.

import matplotlib.pyplot as plt
import numpy as np

def energy_rank(data, marker_width=.5, color='blue'):
    y_data = np.repeat(data, 2)
    x_data = np.empty_like(y_data)
    x_data[0::2] = np.arange(1, len(data)+1) - (marker_width/2)
    x_data[1::2] = np.arange(1, len(data)+1) + (marker_width/2)
    lines = []
    lines.append(plt.Line2D(x_data, y_data, lw=1, linestyle='dashed', color=color))
    for x in range(0,len(data)*2, 2):
        lines.append(plt.Line2D(x_data[x:x+2], y_data[x:x+2], lw=2, linestyle='solid', color=color))
    return lines

data = np.random.rand(4,8) * 4 # 4 lines with 8 datapoints from 0 - 4

artists = []
for row, color in zip(data, ('red','blue','green','magenta')):
    artists.extend(energy_rank(row, color=color))

fig, ax = plt.subplots()

for artist in artists:
    ax.add_artist(artist)
ax.set_ybound([0,4])
ax.set_xbound([.5,8.5])
Aaron
  • 10,133
  • 1
  • 24
  • 40
1

I'm not sure this is technically an answer to this question but I developed a tkinter-based Python application for plotting these graphs in a straightforward manner.

I think it may be useful, please check it out at:
https://github.com/ricalmang/mechaSVG

Here is how the user interface looks like: Here is how the user interface looks like

Here is how a typical output graph looks like: Here is how a typical output graph looks like

Technical Note:
Under the hood, the procedural generation of the corresponding SVG code (generating element by element) is used for the graph preparation. Most of this is done via a class named SvgGenEsp that won't be detailed here simply because it is too lengthy (300+ lines of code).

Gino Mempin
  • 25,369
  • 29
  • 96
  • 135
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - [From Review](/review/low-quality-posts/26349203) – Gino Mempin Jun 08 '20 at 01:04
  • I appreciate the suggestions and edited my answer accordingly. – Ricardo Almir Angnes Jun 08 '20 at 04:38